创建线程三种方法

news2024/10/7 20:36:59

创建和运行线程

方法一,直接使用 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();

方法二,使用 Runnable 配合 Thread

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

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

例如:

public class Test2 {
	public static void main(String[] args) {
		//创建线程任务
		Runnable r = () -> {
            //直接写方法体即可
			System.out.println("Runnable running");
			System.out.println("Hello Thread");
		};
		//将Runnable对象传给Thread
		Thread t = new Thread(r);
		//启动线程
		t.start();
	}
}

方法三:使用FutureTask与Thread结合

使用FutureTask可以用泛型指定线程的返回值类型(Runnable的run方法没有返回值)

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);
public class Test3 {
	public static void main(String[] args) throws ExecutionException, InterruptedException {
        //需要传入一个Callable对象
		FutureTask<Integer> task = new FutureTask<Integer>(new Callable<Integer>() {
			@Override
			public Integer call() throws Exception {
				System.out.println("线程执行!");
				Thread.sleep(1000);
				return 100;
			}
		});

		Thread r1 = new Thread(task, "t2");
		r1.start();
		//获取线程中方法执行后的返回结果
		System.out.println(task.get());
	}
}

方式四:使用线程池例如用Executor框架

参数介绍

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

* @param corePoolSize the number of threads to keep in the pool, even * if they are idle, unless {@code allowCoreThreadTimeOut} is set

池中一直保持的线程的数量,即使线程空闲也不会释放。除非设置了 allowCoreThreadTimeOut *

@param maximumPoolSize the maximum number of threads to allow in the * pool

池中允许的最大的线程数

* @param keepAliveTime when the number of threads is greater than * the core, this is the maximum time that excess idle threads * will wait for new tasks before terminating.

当线程数大于核心线程数的时候,线程在最大多长时间没有接到新任务就会终止释放, 最终线程池维持在 corePoolSize 大小

* @param unit the time unit for the {@code keepAliveTime} argument

时间单位

* @param workQueue the queue to use for holding tasks before they are* executed. This queue will hold only the {@code Runnable} * tasks submitted by the {@code execute} method.

阻塞队列,用来存储等待执行的任务,如果当前对线程的需求超过了 corePoolSize

大小,就会放在这里等待空闲线程执行。

* @param threadFactory the factory to use when the executor * creates a new thread

创建线程的工厂,比如指定线程名等

* @param handler the handler to use when execution is blocked * because the thread bounds and queue capacities are reached

拒绝策略,如果线程满了,线程池就会使用拒绝策略

运行原理: 

1、线程池创建,准备好 core 数量的核心线程,准备接受任务

2、新的任务进来,用 core 准备好的空闲线程执行。

(1) 、core 满了,就将再进来的任务放入阻塞队列中。空闲的 core 就会自己去阻塞队 列获取任务执行

(2) 、阻塞队列满了,就直接开新线程执行,最大只能开到 max 指定的数量

(3) 、max 都执行好了。Max-core 数量空闲的线程会在 keepAliveTime 指定的时间后自 动销毁。最终保持到 core 大小

(4) 、如果线程数开到了 max 的数量,还有新任务进来,就会使用 reject 指定的拒绝策 略进行处理

3、所有的线程创建都是由指定的 factory 创建的。

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

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

相关文章

Doris的安装

Doris的安装 文章目录 Doris的安装写在前面Linux 操作系统版本需求软件需求操作系统安装要求设置系统最大打开文件句柄数时钟同步关闭交换分区&#xff08;swap&#xff09; 开发测试环境生产环境 安装下载安装包默认端口集群部署前置准备安装部署FE安装部署BE在 **FE** 中添加…

2.1C++派生

C派生概述 C中的派生允许从一个已有的类中创建一个新的类&#xff0c;该新类继承了原有类的属性和方法。 派生类可以增加新的属性和方法&#xff0c;也可以重写原有类的方法以改变其行为。 C中的派生类可以通过公有、私有和保护继承来继承基类的成员。 公有继承允许派生类访…

网络协议驱动互联网

在分布式系统中&#xff0c;数据通过各种网络协议在网络中传输。作为应用程序开发者&#xff0c;这往往在问题出现之前似乎是一个黑盒子。 在本文中&#xff0c;我们将解释常见网络协议的工作原理&#xff0c;它们在分布式系统中的应用以及我们如何解决常见问题。后续还会介绍一…

开源一键拥有你自己的ChatGPT+Midjourney网页服务,用不用是另一回事,先收藏!

功能支持 原ChatGPT-Next-Web所有功能 midjourney imgine 想象 midjourney upscale 放大 midjourney variation 变幻 midjourney describe 识图 midjourney blend 混图 midjourney 垫图 绘图进度百分比、实时图像显示 自身支持midjourney-api 参数说明 MIDJOURNEY_PROXY_URL …

组态王与多台PLC之间无线以太网通信

在实际系统中&#xff0c;同一个车间里分布多台PLC&#xff0c;通过上位机集中控制。通常所有设备距离在几十米到上百米不等。在有通讯需求的时候&#xff0c;如果布线的话&#xff0c;工程量较大耽误工期&#xff0c;这种情况下比较适合采用无线通信方式。 本方案以组态王和2…

java -D详解

官方文档对 -D 有明确的解释&#xff0c;具体看 https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html 简单解释一下 首先&#xff0c;java 命令是这么用的 其次&#xff0c;-D 是属于 [options] 这一块的。而 [options] 又分为如下几类 -D 就属于标准选…

企业级医疗项目:码猿慢病云管理系统来了!

大家好&#xff0c;我是不才陈某~ 不知不觉转行到医疗领域已经两年多了&#xff0c;前后服务过三百多家医疗机构&#xff0c;深耕于医疗领域&#xff0c;不知道在座的各位有从事医疗领域工作的吗&#xff1f; 上个月和朋友搞了一套的企业级的医疗实战项目&#xff1a;码猿慢病云…

Arthas线上故障案例分析——内存使用率上升,负载突然变高

使用经验分享 线上故障排查思路&#xff1a; 1、紧急处理&#xff0c;优先保障服务可用&#xff08;如切换vip&#xff0c;主备容灾&#xff09; 2、保留第一现场&#xff0c;通过jstack -l {pid} > jvmtmp.txt &#xff0c;打印栈信息 &#xff08;后续可以在gceasy官网上…

Maven插件开发及Demo演示

引言 maven不仅仅只是项目的依赖管理工具&#xff0c;其强大的核心来源自丰富的插件&#xff0c;可以说插件才是maven工具的灵魂。本篇文章将对如何自定义maven插件进行讲解&#xff0c;希望对大家有所帮助。 背景 讲如何开发maven插件之前&#xff0c;不妨先来聊一下什么是…

STM32速成笔记—定时器

文章目录 一、什么是定时器二、定时器有什么用三、通用定时器详细介绍3.1 时钟来源3.2 预分频器&#xff0c;计数器&#xff0c;自动重装载寄存器3.2.1 预分频器3.2.2 计数器3.2.3 自动重装载寄存器 3.3 触发控制器 四、PWM4.1 什么是PWM4.2 什么是占空比4.3 STM32F1 PWM介绍4.…

【Python 随练】打印菱形图案

题目&#xff1a; 打印出如下图案&#xff08;菱形&#xff09; ********* ****************简介&#xff1a; 在本篇博客中&#xff0c;我们将使用Python代码打印一个菱形图案。我们将提供问题的解析&#xff0c;并给出一个完整的代码示例来生成这个菱形图案。 问题分析&am…

阿里云开源离线同步工具DataX3.0,用于数据仓库、数据集市、数据备份

DataX是阿里云开源的一款离线数据同步工具&#xff0c;支持多种数据源和目的地的数据同步&#xff0c;包括但不限于MySQL、Oracle、HDFS、Hive、ODPS等。它可以通过配置文件来定义数据源和目的地的连接信息、数据同步方式、数据过滤等&#xff0c;从而实现数据的高效、稳定、可…

C++初阶—完善适配器(反向迭代器)

目录 0. 前言 1、反向迭代器定义 2、反向迭代器需要实现的相关函数 3、反向迭代器分析 4、针对vector物理空间结构分析 5、针对list物理空间结构分析 6、反向迭代器适配器的实现及测试 0. 前言 本篇文章主要根据前面所实现的STL中支持迭代器的容器进行完善&#xff0c;使…

Mysql数据库日志和数据的备份恢复(去看一看海吧)

文章目录 一、数据库备份的重要性二、数据库备份的分类1.物理备份&#xff1a;对数据库操作系统的物理文件&#xff08;如数据文件、日志文件等)的备份。2.逻辑备份&#xff1a;对数据库逻辑组件&#xff08;如表等数据库对象&#xff09;的备份&#xff0c;导出sql文件。3.完全…

被卖到 2w 的 ChatGPT 提示词 Prompt 你确定不想要吗?

有朋友说&#xff0c;用 ChatGPT 生成的文案刻板化&#xff0c;格式化&#xff0c;而且往往也不是我想要的。‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ 想要用好 ChatGPT 人工智能工具太难了&#xff0c;想一个好的提示词&#xff0c;也太不容易了&#xff0c;ChatGPT 就像一个宝藏…

3ds MAX绘制休闲椅

首先绘制一个长方形&#xff0c;并用上边两端点和底边中点绘制一个样条曲线 将上述曲线旋转复制&#xff0c;形成一个交叉的样条曲线&#xff0c;并移动两端点的位置&#xff0c;形成一上一下的结构 这就是休闲椅的大致形状 通过创建线将四个端点连接起来&#xff0c;形成空间…

UI组件——滑块简介

滑块控件是调整音量和亮度等设置的首选解决方案。它们立即生效&#xff0c;并允许用户通过移动手柄来微调值。滑块可以很好地达到目的&#xff0c;尤其是在精度不是很重要的情况下。 但是&#xff0c;这些控件可能会令人困惑&#xff0c;难以抓取并设置为精确值。另外&#xf…

人类智能的未来在于东西方智能的融合

有人认为&#xff1a;“只有时空的对齐&#xff0c;没有价值的对齐&#xff0c;智能或许就是智障”&#xff0c;即智能技术必须要与人类的价值观念和道德标准相一致&#xff0c;否则它所产生的结果可能会对人类社会造成负面影响。在现代社会中&#xff0c;智能技术已经越来越广…

【Elacticsearch】 分片副本机制,集群发现机制 ,负载机制,容错机制,扩容机制, 分片路由原理

集群发现机制 Elasticsearch采用了master-slave模式&#xff0c; ES会在集群中选取一个节点成为主节点&#xff0c;只有Master节点有资格维护全局的集群状态&#xff0c;在有节点加入或者退出集群的时候&#xff0c;它会重新分配分片&#xff0c;并将集群最新状态发送给集群中其…

Netty中的零拷贝机制

零拷贝机制(Zero-Copy)是在操作数据时不需要将数据从一块内存区域复制到另一块内存区域的技术,这样就避免了内存的拷贝,使得可以提高CPU的。零拷贝机制是一种操作数据的优化方案,通过避免数据在内存中拷贝达到的提高CPU性能的方案。 1.操作系统的零拷贝机制 操作系统的存储空间…