多线程的入门(二)线程实现与初步使用

1.实现Runable接口

实现Runable接口,实现run方法;

        这种方式创建的线程实现类执行时需要创建Thread实例去运行该任务

示例如下:

package com.example.springbootdamo.Thread;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class RunnableTest implements Runnable{
    static Logger log = LogManager.getLogger();
    @Override
    public void run() {
        log.info("实现Runable接口的线程任务执行中");
    }
}
public static void runable(ThreadPoolExecutor poolExecutor) {
    //创建线程任务对象
    RunnableTest runnableTest = new RunnableTest();
    //调用方法的线程执行
    runnableTest.run();
    //线程调用
    Thread thread = new Thread(runnableTest);
    //重开线程执行
    thread.start();
    //调用方法的线程执行
    thread.run();
    //无返回值的线程池运行任务
    poolExecutor.execute(runnableTest);
    //有返回值的线程池运行任务
    Future<?> submit = poolExecutor.submit(runnableTest);
}

运行图如下:

1.继承Thread类

继承Thread类,重写run方法;直接运行run方法 ,调用start(),或者交由线程池执行

package com.example.springbootdamo.Thread;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.concurrent.TimeUnit;

/**
 * @ClassName ThreadTest
 * @Description TODO
 * @Author zoro
 * @Date 2024/4/4 22:24
 */
public class ThreadTest extends Thread{

    static Logger log = LogManager.getLogger();

    @Override
    public void run(){
        log.info(this.getName()+"继承Thread类的线程任务执行开始");
        try {
            //睡五秒
            this.sleep(5);
            log.info(this.getName()+"继承Thread类的线程任务执行了五秒钟");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info(this.getName()+"继承Thread类的线程任务执行结束");
    }

}

运行示例图如下:由日志是被那个线程所以打印的可知当前执行线程为何

3.实现Callable接口

实现Callable接口,实现call方法,利用FutureTask的构造器(入参为callable对象的实现类)创建实例,调用该对象的run方法或者直接用线程池执行该实例,FutureTask实现了RunnableFuture接口,RunnableFuture实现了Runnable与Future接口。

方法实现:

public static void callable(ThreadPoolExecutor poolExecutor) {
    CallableTest callable = new CallableTest();
    FutureTask futureTask = new FutureTask<>(callable);
    //运调用方法的线程行
    futureTask.run();
    //线程池调用
    poolExecutor.execute(futureTask);
    //线程池运行时,调用方法的线程等待返回值
    //方式一
    Future<ResponseBO> submit = poolExecutor.submit(callable);
    //方式二
    poolExecutor.submit(futureTask);
    try {
        //方式一
        ResponseBO responseBO = submit.get();
        log.info(responseBO.getReturnMessage());
        //方式二
        ResponseBO responseBO2 = (ResponseBO) futureTask.get();
        log.info(responseBO2.getReturnMessage()+"+++");
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    }

运行结果:因为返回值问题,所以调用线程会等待线程执行完任务后继续执行。从下方线程池的工作任务队列workers可知三次都是重新创建的线程

4.线程池创建线程

主要是通过线程池工厂创建

public void threadPool(){
    //默认线程池工厂
    ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(5, 5, 5000, TimeUnit.SECONDS, new LinkedBlockingDeque<>());
    //自定义线程池工厂
    ThreadPoolExecutor poolExecutor1 = new ThreadPoolExecutor(5, 5, 5000, TimeUnit.SECONDS, new LinkedBlockingDeque<>(),new ThreadFactoryTest());
}

线程池创建的线程需要有执行任务对象该对象一般要实现Runable接口或者Callable接口

执行方法有 submit()和execute()两种方式,前者有返回值,后者没有返回值

示例如下:

package com.example.springbootdamo.Thread;

import com.example.springbootdamo.ResponseBO;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.concurrent.*;

public class ThreadPoolTest {

    static Logger log = LogManager.getLogger();

    public static void main(String[] args) {
        //创建线程池
        ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(5, 5, 5000, TimeUnit.SECONDS, new LinkedBlockingDeque<>());
        callable(poolExecutor);
        runable(poolExecutor);
        thread(poolExecutor);
        log.info("日志打印测试");
    }

    public static void callable(ThreadPoolExecutor poolExecutor) {
        CallableTest callable = new CallableTest();
        FutureTask futureTask = new FutureTask<>(callable);
        //线程池调用
        poolExecutor.execute(futureTask);
        //线程池运行时,调用方法的线程等待返回值
        //方式一
        Future<ResponseBO> submit = poolExecutor.submit(callable);
        //方式二
        poolExecutor.submit(futureTask);
        try {
            //方式一
            ResponseBO responseBO = submit.get();
            log.info(responseBO.getReturnMessage());
            //方式二
            ResponseBO responseBO2 = (ResponseBO) futureTask.get();
            log.info(responseBO2.getReturnMessage()+"+++");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }


    public static void runable(ThreadPoolExecutor poolExecutor) {
        //创建线程任务对象
        RunnableTest runnableTest = new RunnableTest();
        //无返回值的线程池运行任务
        poolExecutor.execute(runnableTest);
        //有返回值的线程池运行任务
        Future<?> submit = poolExecutor.submit(runnableTest);
    }
    public static void thread(ThreadPoolExecutor poolExecutor) {
        //创建线程任务对象
        ThreadTest threadTest = new ThreadTest();
        //线程池运行任务
        poolExecutor.execute(threadTest);
        // 执行的是线程的任务
        poolExecutor.submit(threadTest, new ResponseBO());
    }

}

运行结果图如下:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/520763.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】

㊙️小明博客主页&#xff1a;➡️ 敲键盘的小明 ㊙️ ✅关注小明了解更多知识☝️ 文章目录 前言一、三子棋的实现思路二、三子棋的实现步骤2.1 先显示游戏的菜单2.2 游戏的具体实现2.2.1 棋盘的初始化2.2.2 展示棋盘2.2.3 下棋&#x1f534;玩家下棋&#x1f534;电脑下棋2.2…

二叉树进阶——手撕二叉搜索树

troop主页&#xff1a;troop 手撕二叉搜索树 1.二叉搜索树的定义2.实现&#xff08;非递归&#xff09;补充结构2.1查找2.2插入2.3删除&#xff08;重要&#xff09;情况1(无孩子&&一个孩子&#xff09; 3.二叉搜索树的应用3.1K模型3.2KV模型3.2.1KV模型的实现 总结二叉…

RUST语言值所有权之内存复制与移动

1.RUST中每个值都有一个所有者,每次只能有一个所有者 String::from函数会为字符串hello分配一块内存 内存示例如下: 在内存分配前调用s1正常输出 在分配s1给s2后调用报错 因为s1分配给s2后,s1的指向自动失效 s1被move到s2 s1自动释放 字符串克隆使用

I2C驱动实验:读取AP3216C设备中寄存器的数据

一. 简介 经过前面几篇文章的学习&#xff0c;已经完成了I2C驱动框架&#xff0c;字符设备驱动框架&#xff0c;编写了 读写 I2C设备中寄存器的数据的代码&#xff0c;文章如下&#xff1a; I2C驱动实验&#xff1a;实现读/写I2C设备寄存器的函数-CSDN博客 本文在此基础上&a…

C#开发中一些常用的工具类分享

一、配置文件读写类 用于在开发时候C#操作配置文件读写信息 1、工具类 ReadIni 代码 using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks;namesp…

不同设备使用同一个Git账号

想要在公司和家里的电脑上用同一个git账号来pull, push代码 1. 查看原设备的用户名和邮箱 第1种方法&#xff0c; 依次输入 git config user.name git config user.email第2种方法&#xff0c; 输入 cat ~/.gitconfig2. 配置新设备的用户名和邮箱 用户名和邮箱与原设备保持…

高效学习方法:冥想背诵,看一句念一句,再每个词分析位置及语法等合理性,忘记哪个词再看猜下为什么会忘,跟自己的表达哪里不一样。

原则&#xff1a;易学则易行&#xff0c;则效果最好。《易经》 你提到的这种学习方法结合了多种记忆和理解技巧&#xff0c;可以帮助提高学习效率。下面是对这种方法的一个详细解释和一些建议&#xff1a; 冥想背诵&#xff1a;通过冥想来集中注意力&#xff0c;可以帮助你在没…

数据如何才能供得出、流得动、用得好、还安全

众所周知&#xff0c;数据要素已经列入基本生产要素&#xff0c;同时成立国家数据局进行工作统筹。目前数据要素如何发挥其价值&#xff0c;全国掀起了一浪一浪的热潮。 随着国外大语言模型的袭来&#xff0c;国内在大语言模型领域的应用也大放异彩&#xff0c;与此同时&#x…

使用YOLOv8训练自己的【目标检测】数据集

文章目录 1.收集数据集1.1 使用开源已标记数据集1.2 爬取网络图像1.3 自己拍摄数据集1.4 使用数据增强生成数据集1.5 使用算法合成图像 2.标注数据集2.1确认标注格式2.2 开始标注 3.划分数据集4.配置训练环境4.1获取代码4.2安装环境 5.训练模型5.1新建一个数据集yaml文件5.2预测…

java中的正则表达式和异常

正则表达式&#xff1a; 作用一&#xff1a;用来校验数据格式是否合法 作用二&#xff1a;在文本中查找满足要求的内容 不用正则表达式&#xff1a;检验QQ号是否合法&#xff0c;要求全部是数字&#xff0c;长度在6-20&#xff0c;不能以0开头 public class test {public stat…

手机扫码查看视频如何实现?扫描二维码在线看视频的制作技巧

现在的学校或者幼儿园会需要拍摄学生的视频&#xff0c;然后展示给其他人查看&#xff0c;为了能够方便用户能够快速的获取文件内容&#xff0c;所以经常会通过生成视频二维码的方法&#xff0c;将二维码分享之后手机扫码来获取视频内容&#xff0c;有效提升用户获取内容的体验…

PTA C 1050 螺旋矩阵(思路与优化)

本题要求将给定的 N 个正整数按非递增的顺序&#xff0c;填入“螺旋矩阵”。所谓“螺旋矩阵”&#xff0c;是指从左上角第 1 个格子开始&#xff0c;按顺时针螺旋方向填充。要求矩阵的规模为 m 行 n 列&#xff0c;满足条件&#xff1a;mn 等于 N&#xff1b;m≥n&#xff1b;且…

160.相交链表

题目描述 解题思路 ————看评论区大神的思路———— 设「第一个公共节点」为 node &#xff0c;「链表 headA」的节点数量为 aaa &#xff0c;「链表 headB」的节点数量为 bbb &#xff0c;「两链表的公共尾部」的节点数量为 ccc &#xff0c;则有&#xff1a; 头节点 …

CSS设置字体样式

目录 前言&#xff1a; 1.font-family&#xff1a; 2.font-style&#xff1a; 3.font-weight&#xff1a; 4.font-size&#xff1a; 5.font-variant&#xff1a; 6.font&#xff1a; 前言&#xff1a; 在网页中字体是重要的组成部分&#xff0c;使用好字体可以让网页更…

第一次在msf控制台中运行search命令提示Module database cache not built yet问题解决

0x00 问题描述 在新装的kali虚拟机中使用msfconsole执行search命令时提示Module database cache not built yet问题&#xff0c;显然&#xff0c;是我们相关的数据库缓存存在问题。 故障现象&#xff1a; 0x01 启动数据库服务 msf中的search功能是基于postgresql来实现的&am…

python学习25:python中的元组(tuple)

python中的元组(tuple) 1.什么是元组&#xff1f; 元组也是容器数据类型的一种&#xff0c;同列表几乎是一样的&#xff0c;都是可以在里面封装多个&#xff0c;不同类型的元素在内&#xff1b;与列表最大的不同就是&#xff1a; 元组一旦被定义&#xff0c;就不能修改 2.元组…

物理层习题及其相关知识(谁看谁不迷糊呢)

1. 对于带宽为50k Hz的信道&#xff0c;若有4种不同的物理状态来表示数据&#xff0c;信噪比为20dB 。&#xff08;1&#xff09; 按奈奎斯特定理&#xff0c;信道的最大传输数据速率是多少&#xff1f;&#xff08;2&#xff09; 按香农定理&#xff0c;信道的最大传输数据速度…

Java设计模式—享元(FlyWeight)模式

享元模式&#xff08;Flyweight&#xff09;&#xff0c;运用共享技术有效地支持大量细粒度的对象 public abstract class Piece {protected PieceColor m_color;protected PiecePos m_pos;public Piece(PieceColor color ,PiecePos pos){m_color color;m_pos pos;}public ab…

Java笔试总结

. 操作系统中关于竞争和死锁的关系下面描述正确的是&#xff1f; A 竞争一定会导致死锁 B 死锁一定由竞争引起 C 竞争可能引起死锁 D 预防死锁可以防止竞争 答案: C 进程的控制信息和描述信息存放在()。 A JCB B PCB C AFT D SFT 答案: B 当系统发生抖动&#xff08;thrash…

元宇宙虚拟空间的场景的渲染(五)

前言 该文章主要讲元宇宙虚拟空间的场景的渲染&#xff0c;基本核心技术点&#xff0c;不多说&#xff0c;直接引入正题。 场景的渲染 下面第二个图中的代码是一个循环渲染逻辑&#xff0c;首先getDelta 获取2次时间的时间间隔&#xff0c;requestAnimationFrame请求我们的一…