并发编程之创建线程的几种方式以及运行的详细解析

news2024/12/25 2:30:02

3.1 创建和运行线程

方法一,直接使用 Thread

// 创建线程对象
Thread t = new Thread() {
    public void run() {
        // 要执行的任务
    }
};
// 启动线程
t.start();

例如:

// 构造方法的参数是给线程指定名字,推荐
Thread t1 = new Thread("t1") {
    @Override
    // run 方法内实现了要执行的任务
    public void run() {
        log.debug("hello");
    }
};
t1.start();

输出:

19:19:00 [t1] c.ThreadStarter - hello

方法二,使用 Runnable 配合 Thread

把【线程】和【任务】(要执行的代码)分开

  • Thread 代表线程

  • Runnable 可运行的任务(线程要执行的代码)

Runnable runnable = new Runnable() {
    public void run(){
        // 要执行的任务
    }
};
// 创建线程对象
Thread t = new Thread( runnable );
// 启动线程
t.start(); 

例如:

// 创建任务对象
Runnable task2 = new Runnable() {
    @Override
    public void run() {
        log.debug("hello");
    }
};
// 参数1 是任务对象; 参数2 是线程名字,推荐
Thread t2 = new Thread(task2, "t2");
t2.start();

输出:

9:19:00 [t2] c.ThreadStarter - hello

Java 8 以后可以使用 lambda 精简代码

// 创建任务对象
Runnable task2 = () -> log.debug("hello");
// 参数1 是任务对象; 参数2 是线程名字,推荐
Thread t2 = new Thread(task2, "t2");
t2.start();
Thread 与 Runnable 的关系

分析 Thread 的源码,理清它与 Runnable 的关系

//Runnable源码
public interface Runnable {
    public abstract void run();
}
//Thread源码(部分)
public class Thread implements Runnable {
    /* What will be run. */
    private Runnable target;
    
    public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }
    
    private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc,
                      boolean inheritThreadLocals) {
        //...
        this.target = target;
       //...
    }
    @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }
小结
  • 方法1 是把线程和任务合并在了一起,方法2 是把线程和任务分开了

  • 用 Runnable 更容易与线程池等高级API 配合

  • 用 Runnable 让任务类脱离了 Thread 继承体系,更灵活

方法三,FutureTask 配合 Thread

FutureTask 能够接收 Callable 类型的参数,用来处理有返回结果的情况

// 创建任务对象
FutureTask<Integer> task3 = new FutureTask<>(() -> {
 log.debug("hello");
 return 100;
});
// 参数1 是任务对象; 参数2 是线程名字,推荐
new Thread(task3, "t3").start();
// 主线程阻塞,同步等待 task 执行完毕的结果
Integer result = task3.get();
log.debug("结果是:{}", result);

输出

19:22:27 [t3] c.ThreadStarter - hello
19:22:27 [main] c.ThreadStarter - 结果是:100

源码分析

//FutureTask源码(部分)
public class FutureTask<V> implements RunnableFuture<V> {
    /** The underlying callable; nulled out after running */
    private Callable<V> callable;
    
    /** The result to return or exception to throw from get() */
    private Object outcome; // non-volatile, protected by state reads/writes
    
    public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
    }
    
    public void run() {
       //...
        try {
            Callable<V> c = callable;
            if (c != null && state == NEW) {
                V result;
                boolean ran;
                try {
                    result = c.call();
                    ran = true;
                } catch (Throwable ex) {
                    result = null;
                    ran = false;
                    setException(ex);
                }
                if (ran)
                    set(result);
            }
        }
        //...
    }
    
    protected void set(V v) {
        if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
            outcome = v;
            UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state
            finishCompletion();
        }
    }
    
    public V get() throws InterruptedException, ExecutionException {
        int s = state;
        if (s <= COMPLETING)
            s = awaitDone(false, 0L);
        return report(s);
    }
    
    private V report(int s) throws ExecutionException {
        Object x = outcome;
        if (s == NORMAL)
            return (V)x;
        if (s >= CANCELLED)
            throw new CancellationException();
        throw new ExecutionException((Throwable)x);
    }
}    
//Callable源码
@FunctionalInterface
public interface Callable<V> {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}

说明:

  • FutureTask内置了一个Callable对象,初始化方法将指定的Callable赋给这个对象。

  • FutureTask实现了Runnable接口,并重写了Run方法,在Run方法中调用了Callable中的call方法,并将返回值赋值给outcome变量

  • get方法就是取出outcome的值。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

04- 基于SpringAMQP封装RabbitMQ,消息队列的Work模型和发布订阅模型

SpringAMQP 概述 使用RabbitMQ原生API在代码中设置连接MQ的参数比较繁琐,我们更希望把连接参数写在yml文件中来简化开发 SpringAMQP是基于AMQP协议定义的一套API规范,将RabbitMQ封装成一套模板用来发送和接收消息 AMQP(Advanced Message Queuing Portocol)是用于在应用程序…

go语言基础笔记

1.基本类型 1.1. 基本类型 bool int: int8, int16, int32(rune), int64 uint: uint8(byte), uint16, uint32, uint64 float32, float64 string 复数&#xff1a;complex64, complex128 复数有实部和虚部&#xff0c;complex64的实部和虚部为32位&#xff0c;complex128的实部…

某赛通电子文档安全管理系统 DecryptApplication 任意文件读取漏洞(2024年3月发布)

漏洞简介 某赛通电子文档安全管理系统 DecryptApplication 接口处任意文件读取漏洞&#xff0c;未经身份验证的攻击者利用此漏洞获取系统内部敏感文件信息&#xff0c;导致系统处于极不安全的状态。 漏洞等级高危影响版本*漏洞类型任意文件读取影响范围>1W 产品简介 …

案例分析篇06:数据库设计相关28个考点(17~22)(2024年软考高级系统架构设计师冲刺知识点总结系列文章)

专栏系列文章推荐: 2024高级系统架构设计师备考资料(高频考点&真题&经验)https://blog.csdn.net/seeker1994/category_12593400.html 【历年案例分析真题考点汇总】与【专栏文章案例分析高频考点目录】(2024年软考高级系统架构设计师冲刺知识点总结-案例分析篇-…

Jmeter入参问题小记

表单入参的时候&#xff0c;这个地方需要勾选&#xff0c;如果不☑️选的话&#xff0c;会提示errorMsg":"Required String parameter code is not present",

Leet code 三步问题

解题思路&#xff1a;动态规划 先观察 1级台阶 1种方法 2级台阶 2种方法 3级台阶 4种方法 4级台阶 7种方法 5级台阶 13种方法 可以看出规律 从3级台阶后 每级台阶需要从前三层台阶和相加 注意&#xff1a;后面值会过大 需要在相加之后就模运算1000000007 代码如下 clas…

.NET高级面试指南专题十八【 外观模式模式介绍,提供了简化的接口,隐藏系统的复杂性】

介绍&#xff1a; 外观模式是一种结构设计模式&#xff0c;它提供了一个统一的接口&#xff0c;用于访问子系统中的一组接口。外观模式定义了一个高层接口&#xff0c;使得子系统更容易使用。 原理&#xff1a; 外观类&#xff08;Facade Class&#xff09;&#xff1a;提供了一…

C++面试问题收集

0 持续更新中 目录 0 持续更新中 1 C语言相关 1.1 malloc/free和new/delete区别 1.2 内存泄漏 1.3 堆区和栈区的区别 1.4 宏定义和const的区别 1.5 多态 1.6 类中的静态成员变量 2 操作系统相关 2.1 进程和&#xff08;用户&#xff09;线程的区别 2.2 系统调用 2.3…

【论文阅读】MoCoGAN: Decomposing Motion and Content for Video Generation

MoCoGAN: Decomposing Motion and Content for Video Generation 引用&#xff1a; Tulyakov S, Liu M Y, Yang X, et al. Mocogan: Decomposing motion and content for video generation[C]//Proceedings of the IEEE conference on computer vision and pattern recognitio…

【Java基础】IO流(二)字符集知识

目录 字符集知识 1、GBK字符集 2、Unicode字符集&#xff08;万国码&#xff09; 3、乱码 4、Java中编码和解码的方法 字符集知识 字符&#xff08;Character&#xff09;&#xff1a;在计算机和电信技术中&#xff0c;一个字符是一个单位的字形、类字形单位或符号的基本信…

最详细数据仓库项目实现:从0到1的电商数仓建设(采集部分)

1、数据库和数据仓库的区别&#xff1a; 数据仓库就是data warehouse&#xff0c;数据小卖店&#xff0c;相当于是对数据加工&#xff0c;计算然后对外提供服务&#xff0c;而不是单纯的存储 2、数据流转过程中数据仓库中的数据源部分 数据源部分的数据**不是只同步数据库当…

YOLOv8改进 | 图像去雾 | 特征融合注意网络FFA-Net增强YOLOv8对于模糊图片检测能力(北大和北航联合提出)

一、本文介绍 本文给大家带来的改进机制是由北大和北航联合提出的FFA-net: Feature Fusion Attention Network for Single Image Dehazing图像增强去雾网络,该网络的主要思想是利用特征融合注意力网络(Feature Fusion Attention Network)直接恢复无雾图像,FFA-Net通过特征…

海格里斯HEGERLS托盘搬运机器人四向车引领三维空间集群设备柔性运维

随着市场的不断迅猛发展变化&#xff0c;在物流仓储中&#xff0c;无论是国内还是海外&#xff0c;都对托盘式解决方案需求量很大。顾名思义&#xff0c;托盘式解决方案简单理解就是将产品放置在托盘上进行存储、搬运和拣选。 面对托盘式方案需求&#xff0c;行业中常见的方案是…

Wechaty 企业微信机器人报:return ‘port‘ in address

1.使用的依赖&#xff1a; "file-box": "^1.5.5", "qrcode": "^1.5.3", "install": "^0.13.0", "grpc/grpc-js": "^1.10.1","juzi/wechaty": "^1.0.65", "juzi/wec…

学习使用js获取当前ip地址的方法,使用第三方API获取ip地址

学习使用js获取当前ip地址的方法,使用第三方API获取ip地址 使用 DNS 查询使用第三方 API 使用 DNS 查询 DNS 是一种用于解析主机名为 IP 地址的系统。可以使用 JavaScript DNS 查询来获取本机IP地址。下面是如何使用 JavaScript 进行DNS查询的示例代码。 <p class"loc…

csp模拟题(201604-2,俄罗斯方块模拟下坠)

题目 问题描述 俄罗斯方块是俄罗斯人阿列克谢帕基特诺夫发明的一款休闲游戏。   游戏在一个15行10列的方格图上进行&#xff0c;方格图上的每一个格子可能已经放置了方块&#xff0c;或者没有放置方块。每一轮&#xff0c;都会有一个新的由4个小方块组成的板块从方格图的上方…

智慧城市物联网建设:提升城市管理效率与居民生活品质

目录 一、智慧城市物联网建设的意义 1、提升城市管理效率 2、改善居民生活品质 3、促进城市可持续发展 二、智慧城市物联网建设面临的挑战 1、技术标准与互操作性问题 2、数据安全与隐私保护问题 3、投资与回报平衡问题 三、智慧城市物联网建设的实施策略 1、制定统一…

让数据在业务间高效流转,镜舟科技与NineData完成产品兼容互认

近日&#xff0c;镜舟科技与NineData完成产品兼容测试。在经过联合测试后&#xff0c;镜舟科技旗下产品与NineData云原生智能数据管理平台完全兼容&#xff0c;整体运行高效稳定。 镜舟科技致力于帮助中国企业构建卓越的数据分析系统&#xff0c;打造独具竞争力的“数据护城河”…

【SysBench】Linux 安装 sysbench-1.20

安装目的是为了对 MySQL 8.0.x 、PostgreSQL 进行基准测试。 0、sysbench 简介 sysbench 是一个可编写脚本的多线程基准测试工具&#xff0c;基于 LuaJIT 。 它最常用于数据库基准测试&#xff0c;但也可以 用于创建任意不涉及数据库服务器的复杂工作负载。 sysbench 附带以…

服务注册与发现:Nacos

为什么需要服务注册与发现 假设 mafeng-user 用户微服务部署了多个实例&#xff08;组成集群模式&#xff09;&#xff0c;如下图所示&#xff1a; 会出现以下几个问题&#xff1a; mafeng-order订单微服务发出Http远程调用时&#xff0c;该如何得知mafeng-user实例的IP和端口…