JAVA创建线程方式有几种

方式1:继承Thread类

步骤:

  1. 创建一个继承于Thread类的子类
  2. 重写Thread的run()方法
  3. 创建当前Thread子类的对象
  4. 通过实例对象调用start()方法,启动线程----》JAVA虚拟机会调用run()方法
    实现:
public class TestMyThread {public static void main(String[] args) {//创建自定义线程对象1MyThread mt1 = new MyThread("子线程1");//开启子线程1mt1.start();//创建自定义线程对象2,分别创建对象开启线程,不可以数据共享,若要共享需要创建static变量MyThread mt2 = new MyThread("子线程2");//开启子线程2mt2.start();}
}
方式2:实现Runnable接口

步骤:

  1. 创建一个实现Runnable接口的类
  2. 实现接口中的run()方法
  3. 创建实例对象
  4. 将此对象作为参数传到Thread类的构造器中,创建Thread类的实例
  5. 通过Thread的实例对象调用start()方法,启用线程—》JAVA虚拟机会调用run()方法
    实现:
public class TestMyRunnable {public static void main(String[] args) {//创建自定义类对象  线程任务对象MyRunnable mr = new MyRunnable();//创建线程对象1Thread t1 = new Thread(mr, "长江1");t1.start();//创建线程对象2,注意两个线程传入的是同一个对象,可以实现数据共享Thread t2 = new Thread(mr, "长江2");t2.start();}
}
方式3:实现Callable接口
  1. 与使用Runnable相比,Callable功能更强大些。
  • 相比run()方法,call()可以有返回值,更灵活。
  • call()方法可以使用throws抛出异常,更灵活
  • Callable使用泛型参数,可以指明具体的call()返回值类型,更灵活。
  1. Future接口
  • 可以对具体Runnable,Callable任务的执行接口进行取消,查询是否完成,获取结果等
  • FutureTask是Future接口的唯一的实现类
  • FutureTask同时实现了Runnable,Future接口。它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。
  1. 缺点:在获取分线程执行结果的时候,当前线程或主线程受阻塞,效率较低。
    实现:
/** 创建多线程的方式三:实现Callable (jdk5.0新增的)*/
//1.创建一个实现Callable的实现类
class NumThread implements Callable {//2.实现call方法,将此线程需要执行的操作声明在call()中@Overridepublic Object call() throws Exception {int sum = 0;for (int i = 1; i <= 100; i++) {if (i % 2 == 0) {System.out.println(i);sum += i;}}return sum;}
}public class CallableTest {public static void main(String[] args) {//3.创建Callable接口实现类的对象NumThread numThread = new NumThread();//4.将此Callable接口实现类的对象作为传递到FutureTask构造器中,创建FutureTask的对象FutureTask futureTask = new FutureTask(numThread);//5.将FutureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象,并调用start()new Thread(futureTask).start();//      接收返回值try {//6.获取Callable中call方法的返回值//get()返回值即为FutureTask构造器参数Callable实现类重写的call()的返回值。Object sum = futureTask.get();System.out.println("总和为:" + sum);} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}}}
方式4: 使用线程池

背景:如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。
思路:提前创建好多个线程,放入线程池中,使用时直接获取,使用完放回池中,可以避免频繁创建销毁,实现重复利用。

线程池
好处:

  • 提高了程序执行的效率(线程已经提前创建好了)
  • 提高了资源复用率(执行完的线程并未销毁,还可以继续执行其他任务,不需要每次都创建)
  • 可以设置相关参数,对线程池中的线程进行管理
corePoolSize: 核心池的大小
maximumPoolSize: 最大线程数
keepAliveTime:线程没有任务时最多保持多长时间后会终止。多余空闲线程的存活时间。当前线程池数量超过corePoolSize时,当空闲时间达到keepAliveTime时,多余空闲线程会被销毁直到剩下corePoolSize为止。
unit: keepAliveTime的单位
workQueue: 里面放了被提交但是尚未执行的任务
threadFactory: 表示线程池中工作线程的线程工厂,用于创建线程
handler: 拒绝策略,当队列满了并且工作线程大于等于线程池的最大线程数时,对任务的拒绝方式。

四种拒绝策略

  • AbortPolicy(默认):直接抛出RejectedExecutionException异常阻止系统正常进行
  • CallerRunsPolicy:调用者运行一种调节机制,该策略既不会抛弃任务,也不会抛出异常,而是将某些任务回退到调用者,从而降低新任务的流量
  • DiscardPolicy: 改变略默默丢弃无法处理的任务,不予任何受理也不抛出异常,如果允许任务丢弃,这是最好的一种策略
  • DiscardOldestPolicy: 抛弃队列中等待最久的任务,然后将当前任务加入队列,然后再次提交任务

ExecutorService: 真正的线程池接口,常见子类ThreadPoolExecutor

void execute(Runnable command): 执行任务命令,没有返回值,一般用来执行Runnable
Future submit(Callable task): 执行任务,有返回值,一般用来执行Callable
void shutdown(): 关闭连接池
  • Executors: 一个线程池的工厂类,通过此类的静态工厂方法可以创建多种类型的线程池对象。
Executors.newCachedThreadPool(): 创建一个可根据需要创建新线程的线程池
Executors.newFixedThreadPool(int  nThreads): 创建一个可重用固定线程数的线程池
Executors.newSingleThreadPool(): 创建一个只有一个线程的线程池
Executors.newScheduledThreadPool(int corePoolSize): 创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。

实现:

// 这里使用实现Runnable的方式
class NumberThread implements Runnable{@Overridepublic void run() {for(int i = 0;i <= 100;i++){if(i % 2 == 0){System.out.println(Thread.currentThread().getName() + ": " + i);}}}
}class NumberThread1 implements Runnable{@Overridepublic void run() {for(int i = 0;i <= 100;i++){if(i % 2 != 0){System.out.println(Thread.currentThread().getName() + ": " + i);}}}
}class NumberThread2 implements Callable {@Overridepublic Object call() throws Exception {int evenSum = 0;//记录偶数的和for(int i = 0;i <= 100;i++){if(i % 2 == 0){evenSum += i;}}return evenSum;}}public class ThreadPoolTest {public static void main(String[] args) {//1. 提供指定线程数量的线程池ExecutorService service = Executors.newFixedThreadPool(10);ThreadPoolExecutor service1 = (ThreadPoolExecutor) service;
//        //设置线程池的属性
//        System.out.println(service.getClass());//ThreadPoolExecutorservice1.setMaximumPoolSize(50); //设置线程池中线程数的上限//2.执行指定的线程的操作。需要提供实现Runnable接口或Callable接口实现类的对象service.execute(new NumberThread());//适合适用于Runnableservice.execute(new NumberThread1());//适合适用于Runnabletry {Future future = service.submit(new NumberThread2());//适合使用于CallableSystem.out.println("总和为:" + future.get());} catch (Exception e) {e.printStackTrace();}//3.关闭连接池service.shutdown();}}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

html实现各种瀑布流(附源码)

文章目录 1.设计来源1.1 动态响应瀑布流1.2 分页瀑布流1.3 响应瀑布流 2.效果和源码2.1 动态效果2.2 源代码 源码下载 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_43151418/article/details/134613121 html实现各种瀑布流(附源码)&#xff0c;…

pwn:[NISACTF 2022]ReorPwn?

题目 按正常方式走&#xff0c;发现指令被反着输出

十大排序之计数排序、桶排序、基数排序(详解)

文章目录 &#x1f412;个人主页&#x1f3c5;算法思维框架&#x1f4d6;前言&#xff1a; &#x1f380;计数排序 时间复杂度O(nk)&#x1f387;1. 算法步骤思想&#x1f387;2.动画实现&#x1f387; 3.代码实现 &#x1f380;桶排序&#x1f387;1. 算法步骤思想&#x1f38…

list的总结

目录 1.什么是list 1.1list 的优势和劣势 优势&#xff1a; 劣势&#xff1a; 2.构造函数 2.1 default (1) 2.2 fill (2) 2.3 range (3) 2.4 copy (4) 3.list iterator的使用 3.1. begin() 3.2. end() 3.3迭代器遍历 4. list容量函数 4.1. empty() 4.2. siz…

开源vs闭源,处在大模型洪流中,向何处去?

文章目录 一、开源和闭源的优劣势比较1.1 开源优势1.2 闭源的优势 二、开源和闭源对大模型技术发展的影响2.1 数据共享2.2 算法创新2.3 业务拓展2.4 安全性和隐私2.5 社会责任和伦理 三、开源与闭源的商业模式比较3.1 盈利模式3.2 市场竞争3.3 用户生态3.4 创新速度 四&#xf…

基于厨师算法优化概率神经网络PNN的分类预测 - 附代码

基于厨师算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于厨师算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于厨师优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神经网络的光滑…

Java Web 学习之路(1) —— 前端篇

文章目录 前言1. JS1.1 引入方式1.2 基础语法1.3 函数1.4 对象1.5 事件监听 2. Vue3. Ajax4. Element5. Nginx 前言 在学习后端前&#xff0c;还需要大致了解下前端的一些知识&#xff0c;所以本篇就先快速把前端的一些知识过一遍。本篇不含过多干货和技术知识&#xff0c;仅仅…

python排序算法_归并排序

什么是归并排序&#xff1a; 归并排序是一种基于分治法的排序算法。它的基本思想是将待排序的序列分成若干个子序列&#xff0c;分别进行排序&#xff0c;然后再将已排序的子序列合并成一个有序的序列。 基本思想&#xff1a; 归并排序是用分治思想&#xff0c;分治模式在每一…

Loadrunner安装大全

目录 一 、下载篇 二、安装篇 三、破解篇 四、Loadrunner支持哪些操作系统&#xff1f; 五、安装Loadrunner需要满足哪些系统要求&#xff1f; 六、安装Loadrunner时是否需要注意什么问题&#xff1f; 七、安装完成后如何验证Loadrunner是否正常工作&#xff1f; 八、如…

网络层(IP协议)

文章目录 网络层IP协议IP协议报头32位源IP地址和目的IP地址:为了解决IP地址不够用的情况 IP地址管理子网掩码特殊IP 路由选择(简介) 网络层 网络层主要负责地址管理和路由选择.代表协议就是IP协议. IP协议 IP协议报头 4位版本: 4: 表示IPv4 ; 6: 表示IPv6 4位首部长度: 描述…

今年的校招薪资真的让人咋舌!

秋招接近尾声&#xff0c;各大公司基本也陆续开奖了。这里整理了部分公司的薪资情况&#xff0c;数据来源于 OfferShow 和牛客网。 ps&#xff1a;爆料薪资的几乎都是 211 和 985 的&#xff0c;并不是刻意只选取学校好的。另外&#xff0c;无法保证数据的严格准确性。 淘天 …

[每周一更]-(第74期):Docker-compose 部署Jenkins容器-英文版及错误纠错

1、前文概要 通过物理机部署Jenkins前文已经讲过&#xff08;地址&#xff1a;[Jenkins] 物理机 安装 Jenkins&#xff09;&#xff0c;也已经公司内部平稳运行若干年&#xff0c;考虑到容器化的使用场景&#xff0c;部分项目都采用容器运行&#xff0c;开始考虑部署容器化的J…