【Java (10-2) 多线程学习】
创始人
2025-05-28 20:56:40
0

多线程学习

四、线程池&volatile

1. 线程状态

在这里插入图片描述
在这里插入图片描述

2. 线程池

线程池的原理类似于用碗吃饭,吃完后放回橱柜(就是线程池),如果这个碗正在使用(A线程),这时需要新的线程B执行,则从橱柜里重新拿碗,如果A线程使用的碗还未归还则需要拿新的碗进行吃饭;
在这里插入图片描述

3. 线程池-Executors

3.1 Executors.newCachedThreadPool();

//创建一个根据需要创建新线程的线程池,但在可用时将重新使用以前构造的线程。
//static ExecutorService newCachedThreadPool()
//创建一个线程池,该线程池重用固定数量的从共享无界队列中运行的线程。
//static ExecutorService newFixedThreadPool(int nThreads)import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ThreadPool {public static void main(String[] args) throws InterruptedException {//创建一个默认线程池对象 默认是空的 默认最大是int的最大值ExecutorService executorService = Executors.newCachedThreadPool();//Executors 帮助我们创建线程池对象//ExecutorService 帮追我们管理线程池executorService.submit(()->{System.out.println(Thread.currentThread().getName()+"在执行了");});//  Thread.sleep(2000);executorService.submit(()->{System.out.println(Thread.currentThread().getName()+"在执行了");});executorService.shutdown();}}

此时之所以是两个线程执行因为线程1执行完还未归还线程池内时,线程2已经执行,所以时两个线程对象
执行结果
在这里插入图片描述

执行时后睡2s后执行,由一个线程对象执行的
在这里插入图片描述

3.2 Executors.newFixedThreadPool();

newFixedThreadPool(10) 这里的值 是线程池的最大值


import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;//创建一个线程池,该线程池重用固定数量的从共享无界队列中运行的线程。
//static ExecutorService newFixedThreadPool(int nThreads)
public class ThreadPool2 {public static void main(String[] args) {ExecutorService executorService = Executors.newFixedThreadPool(10);executorService.submit(()->{System.out.println(Thread.currentThread().getName()+"在执行了");});executorService.submit(()->{System.out.println(Thread.currentThread().getName()+"在执行了");});executorService.shutdown();}
}//获取最大线程池容量import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;//创建一个线程池,该线程池重用固定数量的从共享无界队列中运行的线程。
//static ExecutorService newFixedThreadPool(int nThreads)
public class ThreadPool2 {public static void main(String[] args) {//参数不是初始值 而是最大值ExecutorService executorService = Executors.newFixedThreadPool(10);ThreadPoolExecutor pool=(ThreadPoolExecutor) executorService;System.out.println(pool.getPoolSize());executorService.submit(()->{System.out.println(Thread.currentThread().getName()+"在执行了");});executorService.submit(()->{System.out.println(Thread.currentThread().getName()+"在执行了");});executorService.shutdown();System.out.println(pool.getPoolSize());}
}

4. 自定义线程池 -ThreadPoolExecutor

在这里插入图片描述
在这里插入图片描述
代码实现


//ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
// BlockingQueue workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
//        创建一个新 ThreadPoolExecutor给定的初始参数。import java.util.concurrent.*;/**** 参数1:核心线程数量* 参数2:最大线程数* 参数3:空闲线程最大存活时间* 参数4:时间单位* 参数5:任务队列  如下最大执行为5个线程,超过5个线程时就要在队列中等待* 参数6:任务创建工厂 按照默认方式创建线程对象 源码中还是new Thread()* 参数7:任务拒绝策略  什么时候拒绝任务?  当提交任务>池子中最大线程数量+任务队列容量           怎样拒绝任务?? * 4种拒绝任务策略*/
public class ThreadPool3 {static class MyRunnable implements  Runnable{@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+"在执行了");}}public static void main(String[] args) {ThreadPoolExecutor pool=new ThreadPoolExecutor(2,5,2,TimeUnit.SECONDS,new ArrayBlockingQueue<>(10),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());pool.submit(new MyRunnable());pool.submit(new MyRunnable());pool.shutdown();}
}
4.1线程池任务拒绝策略

4.1.1 new ThreadPoolExecutor.AbortPolicy()

超过线程池中线程最大容量+任务队列容量时:丢弃任务并抛出异常

代码实现


import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;/**** 参数1:核心线程数量* 参数2:最大线程数* 参数3:空闲线程最大存活时间* 参数4:时间单位* 参数5:任务队列* 参数6:任务创建工厂* 参数7:任务拒绝策略*/
public class ThreadPool4 {static class MyRunnable implements  Runnable{@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+"在执行了");}}public static void main(String[] args) {ThreadPoolExecutor pool=new ThreadPoolExecutor(2,5,2,TimeUnit.SECONDS,new ArrayBlockingQueue<>(10),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());for (int i = 1; i <= 16; i++) {pool.submit(new MyRunnable());}pool.shutdown();}
}
4.1.2 new ThreadPoolExecutor.DiscardPolicy()

直接丢弃 不抛异常


public class ThreadPool4 {static class MyRunnable implements  Runnable{@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+"在执行了");}}public static void main(String[] args) {ThreadPoolExecutor pool=new ThreadPoolExecutor(1,2,2,TimeUnit.SECONDS,new ArrayBlockingQueue<>(1),Executors.defaultThreadFactory(),new ThreadPoolExecutor.DiscardPolicy());for (int i = 1; i <= 5; i++) {int y=i;pool.submit(()->{
System.out.println(Thread.currentThread().getName()+"*****"+y);});}pool.shutdown();}
}

执行结果:
在这里插入图片描述

4.1.3 new ThreadPoolExecutor.DiscardOldestPolicy()

抛弃队列中等待最久,加入当前任务进入队列
直接放结果
在这里插入图片描述

4.1.4 new ThreadPoolExecutor.CallerRunsPolicy()

在这里插入图片描述

5. volatile关键字

强制线程每次使用的时候,都会看一下共享区域最新的值
对 volatile 修饰的变量值,保证线程读取到的值是最新的,而不是寄存器中缓存的值。
在这里插入图片描述
在这里插入图片描述


class Money {public  static volatile  int money=100000;public static void main(String[] args) {MyThead1 t1=new MyThead1();MyThead2 t2=new MyThead2();t2.start();t1.start();}
}
class MyThead2  extends  Thread{
@Override
public void run() {try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}Money.money=90000;}}public class MyThead1  extends  Thread{@Overridepublic void run() {while (Money.money==100000){}System.out.println("结婚基金已经不是10万了");}
}
5.1 synchronized解决

代码实现:


class Money {public static volatile int money = 100000;public static Object lock = new Object();public static void main(String[] args) {MyThead1 t1 = new MyThead1();MyThead2 t2 = new MyThead2();t2.start();t1.start();}
}class MyThead2 extends Thread {@Overridepublic void run() {synchronized (Money.lock){try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}Money.money = 90000;}}
}public class MyThead1 extends Thread {@Overridepublic void run() {while (true) {synchronized (Money.lock) {if (Money.money != 100000) {System.out.println("结婚基金已经不是10万了");break;}}}}
}

原理:
在这里插入图片描述

相关内容

热门资讯

《最高人民法院关于审理建设工程... 为深入贯彻习近平法治思想,认真落实党的二十届四中全会精神,正确审理建设工程施工合同纠纷案件,统一法律...
【金昌】老百姓的“声音”,是这... 编 者 按 人民,是推动经济社会发展的主角;基层,是新闻永不枯竭的源头。为深入学习和践行“四力”要求...
中国公民应立即撤离!外交部、中... 来源:“领事直通车”微信公众号 原标题:《安全提醒:驻留刚果(金)东部地区中国公民应立即撤离》 “领...
中国火箭军:假如战争今天爆发,... 11月23日,中国火箭军 @东风快递 官方账号发布高燃视频: 假如战争今天爆发,这就是我的回答! ...
河北省深入开展安责险政策宣贯活... 长城网·冀云客户端讯(记者 段永亮 何震)为全面落实国家关于安全生产责任保险工作的决策部署,深入解读...
TikTok因数据隐私问题面临... 据evrimagaci报道,以其令人欲罢不能的短视频而闻名的社交媒体巨头TikTok,如今在加拿大陷...
专家解读|推动大型网络平台个人... 大型网络平台作为个人信息处理的核心载体,其用户规模往往数以亿计,业务覆盖社交、购物、金融、娱乐等多元...
应用实践陆续展开,他们牵头开发... 在人工智能浪潮奔涌的上海徐汇,法律科技正从辅助工具演进为驱动创新的核心基础设施,为全球企业构筑安全、...
美国关税“备用方案”曝光,多名... 周末,关税领域传来一个大消息! 据外媒报道,特朗普政府正在秘密准备一套备用方案,如果美国最高法院推翻...
被起诉侵权,视觉中国公开致歉:... 南方都市报(nddaily)报道 见习记者 付冰洁 南都N视频记者 马辉 11月22日,南都N视频记...