【并发编程】创建线程的三种方法

news2024/11/15 17:39:37

源码

Runnable

函数式接口

package java.lang;  
@FunctionalInterface  
public interface Runnable {  
public abstract void run();  
}

Thread

就是一个典型的静态代理模式

public   class Thread implements Runnable {
	private Runnable target;
	public Thread() {  
	    init(null, null, "Thread-" + nextThreadNum(), 0);  
    }  
    public Thread(Runnable target) {  
	    init(null, target, "Thread-" + nextThreadNum(), 0);  
	}
	@Override  
	public void run() {  
	    if (target != null) {  
	        target.run();  
	    }  
	}
}

FutureTask

FutureTask的run()实际上调用的是Callable的call()方法,返回的realut可以通过get()方法获取

public void run() {  
    if (state != NEW ||  
        !UNSAFE.compareAndSwapObject(this, runnerOffset,  
                                     null, Thread.currentThread()))  
        return;  
    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);  
        }  
    } finally {   
        if (s >= INTERRUPTING)  
            handlePossibleCancellationInterrupt(s);  
    }  
}
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);  
}

类图

image.png

一、继承Thread

继承Thread,重写run方法

    @Test  
    public void test2(){  
        // 创建线程对象  
        Thread t = new subThread();  
        // 启动线程  
        t.start();  
    }  

class subThread extends Thread{  
    @Override  
    public void run() {  
        System.out.println("任务1");  
    }  
}

或者

匿名子类

@Test  
public void test1(){  
    // 创建线程对象  
    Thread t = new Thread() {  
        @Override  
        public void run() {  
            System.out.println("任务1.1");  
        }  
    };  
    // 启动线程  
    t.start();  
}

二、给Thred对象传入Runnable对象(推荐)

    @Test  
    public void test3(){  
        Runnable runnable = new RunnableImpl();  
        Thread thread = new Thread(runnable);  
        thread.start();  
    }  

class RunnableImpl implements  Runnable{  
    @Override  
    public void run() {  
        System.out.println("任务2");  
    }  
}

推荐写法,使用lamada表达式生成Runable的匿名内部类对象,再传给Thred对象。
把任务和线程分开,更加灵活

@Test  
public void test4(){  
    Runnable runnable = () -> System.out.println("任务2.2");  
    Thread thread = new Thread(runnable);  
    thread.start();  
}

原理
Thread的run方法,使用到了静态代理模式,执行thred对象的run实际上执行的是匿名Runnable实现类对象的run方法。

@Override  
public void run() {  
    if (target != null) {  
        target.run();  
    }  
}

三、给Thread对象传入FutureTask对象

@Test  
public void test5() throws ExecutionException, InterruptedException {  
    // 创建任务对象  
    FutureTask<Integer> task3 = new FutureTask<>(() -> {  
        System.out.println("任务3");  
        return 100;  
    });  
    // 参数1 是任务对象; 参数2 是线程名字,推荐  
    new Thread(task3, "t3").start();  
    // 主线程阻塞,同步等待 task 执行完毕的结果  
    Integer result = task3.get();  
    System.out.println(result);  
  
}

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

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

相关文章

接口测试用例如何编写?

目录 前言&#xff1a; 在开始编写接口测试用例之前&#xff0c;需要注意几件事&#xff1a; 编写接口测试用例的步骤包括&#xff1a; 常遇到的问题包括&#xff1a; 前言&#xff1a; 编写接口测试用例是接口测试的重要一环。好的接口测试用例能够充分覆盖接口各种情况&…

jmeter负载测试中如何找到最大并发用户数(实战)

目录 前言 负载测试概念 脚本总体设计&#xff1a; 场景介绍&#xff1a; 前言 在进行负载测试时&#xff0c;找到最大并发用户数是非常重要的&#xff0c;这个值将会告诉您系统可以承受多大的并发请求。 在性能测试中&#xff0c;当我们接到项目任务时&#xff0c;很多时…

热烈Matplotlib子图不不会画来看看-分图绘制(怒肝万字)

&#x1f468;&#x1f3fb;‍&#x1f393;博主介绍&#xff1a;大家好&#xff0c;我是大锤爱编程的博客_CSDN博客-大数据,Go,数据分析领域博主&#xff0c;有五年的数据开开发&#xff0c;有着丰富的数仓搭建、数据分析经验。我会在我的系列文章里面分享我学到的知识&#x…

计算机服务器中了encrypted勒索病毒怎么办,什么是encrypted勒索病毒

Encrypted勒索病毒是一种非常危险的电脑病毒&#xff0c;该病毒通过加密计算机中的文件和数据&#xff0c;使其无法访问和使用计算机&#xff0c;并要求受害者支付一定的赎金以获得解密密钥。 Encrypted勒索病毒是一种常见的勒索软件&#xff0c;由于它使用先进的加密技术&…

ansible的部署和模块

一、 ansible 的概述 1、ansible简介 Ansible是一款为类Unix系统开发的自由开源的配置和自动化工具。 它用Python写成&#xff0c;类似于saltstack和Puppet&#xff0c;但是有一个不同和优点是我们不需要在节点中安装任何客户端。 它使用SSH来和节点进行通信。Ansible基于 …

【OpenCV DNN】Flask 视频监控目标检测教程 09

欢迎关注『OpenCV DNN Youcans』系列&#xff0c;持续更新中 【OpenCV DNN】Flask 视频监控目标检测教程 09 3.9 OpenCVFlask多线程处理实时监控人脸识别新建 Flask 项目 cvFlask09Python程序文件视频流的网页模板程序运行 本系列从零开始&#xff0c;详细讲解使用 Flask 框架…

Windows版Redis安装

最近电脑重装了系统&#xff0c;很多常用的软件、应用都没有了&#xff0c;所以需要重新装&#xff0c;所以想借此机会把一些安装比较复杂的应用的安装过程&#xff0c;重新记录一下&#xff0c;方便后续&#xff0c; 安装 Redis默认只有Linux的版本&#xff0c;但是微软为了更…

Python面向对象编程1-面向过程的简单纸牌游戏程序 项目1.4 打印牌的点数和花色

总项目目标&#xff1a;用面向过程思想设计一个简单的纸牌游戏程序&#xff0c;称为"Higher or Lower"&#xff08;高还是低&#xff09;。游戏中&#xff0c;玩家需要猜测接下来的一张牌是比当前牌高还是低。根据猜测的准确性&#xff0c;玩家可以得到或失去相应的积…

容器(第九篇)ansible-playbook

Ansible 的脚本 --- playbook 剧本 playbooks 本身由以下各部分组成 &#xff08;1&#xff09;Tasks&#xff1a;任务&#xff0c;即通过 task 调用 ansible 的模板将多个操作组织在一个 playbook 中运行 &#xff08;2&#xff09;Variables&#xff1a;变量 &#xff08;3&…

pytorch搭建LeNet网络实现图像分类器

pytorch搭建LeNet网络实现图像分类器 一、定义LeNet网络模型1&#xff0c;卷积 Conv2d2&#xff0c;池化 MaxPool2d3&#xff0c;Tensor的展平&#xff1a;view()4&#xff0c;全连接 Linear5&#xff0c;代码&#xff1a;定义 LeNet 网络模型 二、训练并保存网络参数1&#xf…

GAMES101笔记 Lecture03 Transformation

目录 Transoformation(变换)Why stuty transformation(为什么要学习变换呢?)2D transformations(2D变换)Scale transformation(缩放变换)Reflection Matrix(反射矩阵)Shear Matrix(切变矩阵) Rotate transformation(旋转变换)Linear Transforms Matrices(线性变换 矩阵) Hom…

Java泛型详解,史上最全图文详解

泛型在java中有很重要的地位&#xff0c;无论是开源框架还是JDK源码都能看到它。 毫不夸张的说&#xff0c;泛型是通用设计上必不可少的元素&#xff0c;所以真正理解与正确使用泛型&#xff0c;是一门必修课。 一&#xff1a;泛型本质 Java 泛型&#xff08;generics&#…

C#程序设计——Windows应用程序开发,1、初步掌握Windows应用程序的设计方法。2、掌握常用窗体控件的使用方法。

Windows应用程序开发 一、实验目的 初步掌握Windows应用程序的设计方法。掌握常用窗体控件的使用方法。 二、实验内容 1、设计一个Windows应用程序&#xff0c;创建一个用于添加学生个人基本信息的窗体&#xff0c;窗体下方法同时滚动信息“天行健&#xf…

前端学习-html基础

html学习与总结 一、基础认知 1.1.1 认识网页&#xff08;了解&#xff09; ➢ 问题1&#xff1a;网页由哪些部分组成&#xff1f; ✓ 文字、图片、音频、视频、超链接 ➢ 问题2&#xff1a;我们看到的网页背后本质是什么&#xff1f; ✓ 前端程序员写的代码 ➢ 问题3&a…

设计模式的几大原则

设计模式原则 前言一.单一职责原则1.1 定义1.2 例子1.3 总结 二.里氏替换原则2.1 定义1.2 例子1.3 总结 三.依赖倒置原则3.1 定义3.2例子3.3总结 四.接口隔离原则4.1 定义4.2 例子4.3 总结五.迪米特法则5.1 定义5.2 例子5.3 总结 六.开闭原则6.1 定义6.2 例子6.3 结论 前言 设…

MongoDB复制(副本)集实战及其原理分析-04

MongoDB复制集 复制集架构 在生产环境中&#xff0c;不建议使用单机版的MongoDB服务器。 原因如下&#xff1a; 单机版的MongoDB无法保证可靠性&#xff0c;一旦进程发生故障或是服务器宕机&#xff0c;业务 将直接不可用。 一旦服务器上的磁盘损坏&#xff0c;数据会直接丢…

UDS系列-31服务(Routine Control)

诊断协议那些事儿 诊断协议那些事儿专栏系列文章,本文介绍例程控制服务RoutineControl,该服务的目的是Client端使用Routine Control服务来执行定义的步骤序列并获取特定序列的相关结果。这个服务经常在EOL、Bootloader中使用,比如,检查刷写条件是否满足、擦除内存、覆盖正…

post接口请求测试,通俗易懂

目录 前言&#xff1a; GET方法和POST方法传递数据的异同 POST方法如何传递数据 接口测试软件简介 POST请求接口的测试 测试方法 3.保存接口测试用例&#xff0c;生成自动化测试套件 总结 前言&#xff1a; Post请求是HTTP中请求方法之一&#xff0c;用于向服务器提交…

AI 绘画(2):Ai模型训练,Embedding模型,实现“人物模型“自由

文章目录 文章回顾感谢人员题外话Ai绘画公约Ai模型训练硬件要求显存设置查看显存大小显存过小解决方法 视频教程前期准备SD配置设置SD设置配置SD训练配置pt生成训练集收集训练集要求截图软件推荐训练集版权声明一键重命名图片训练图片来源批量修改图片尺寸 开始训练导入训练集&…

MQTTX的使用

1.MQTT介绍 MQTT是一种常用的物联网协议。MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一种轻量级的发布/订阅通信协议&#xff0c;用于在物联网&#xff08;IoT&#xff09;和机器对机器&#xff08;M2M&#xff09;通信中传输消息。 MQTT协议被设计用…