【Java (10-2) 多线程学习】
创始人
2025-05-28 20:22:13
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;}}}}
}

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

相关内容

热门资讯

安卓系统韩文字体替换,安卓系统... 你是不是也和我一样,在使用安卓手机的时候,发现韩文字体实在是不太对胃口?别急,今天就来给你详细聊聊安...
安卓系统如何固定定位,固定与动... 你是不是也和我一样,在使用安卓手机时,总是被那些不固定的定位给弄得头疼?别急,今天就来手把手教你如何...
安卓上面怎么装系统,安卓设备系... 你有没有想过,手机用久了,是不是有点儿腻味了呢?想要给它换换口味,换一个全新的操作系统?别急,今天就...
安卓7.0系统淘汰了吗,回顾与... 你有没有发现,手机里的安卓系统更新换代的速度简直就像坐上了火箭呢!这不,最近就有小伙伴问我:“安卓7...
安卓系统最新的是什么,引领智能... 你有没有发现,你的手机最近是不是总在提醒你更新系统?没错,这就是安卓系统在默默为你升级,让你的手机体...
安卓系统哪个机子最好用,盘点最... 你有没有想过,在这个科技飞速发展的时代,拥有一台好用的安卓手机是多么重要的一件事呢?想象每天陪伴你的...
安卓系统成长视频在哪看,揭秘成... 你有没有想过,安卓系统从一个小小的胚胎成长为如今庞大的生态圈,这其中的点点滴滴是不是特别有意思呢?想...
蝴蝶视频apk安卓系统,安卓系... 你有没有想过,在手机上欣赏蝴蝶翩翩起舞的美丽瞬间?现在,有个神奇的APP能让你随时随地实现这个愿望!...
无刘海手机安卓系统推荐,安卓系... 你有没有发现,最近市面上越来越多的手机开始流行无刘海设计了?这不仅仅是一种潮流,更是一种对手机屏幕视...
安卓系统会被垄断吗,垄断危机与... 你有没有想过,那个陪伴我们手机生活的安卓系统,会不会有一天被某个巨头垄断了呢?想象如果只有一家公司能...
安卓系统怎么变苹果贴纸,揭秘如... 你有没有想过,把安卓手机的系统风格变成苹果的,是不是瞬间高大上呢?没错,今天就来教你怎么把安卓系统变...
原车安卓系统刷机,解锁性能新境... 你有没有想过,你的爱车原车安卓系统是不是有点儿“老态龙钟”了呢?别急,今天就来给你揭秘一下原车安卓系...
安卓系统怎么设置翻译,安卓系统... 你是不是也和我一样,在使用安卓手机的时候,遇到了需要翻译的场景,但又不知道怎么设置翻译功能呢?别急,...
安卓的系统设置在哪里,不同版本... 亲爱的手机控们,你是不是有时候在安卓手机上翻来覆去,就是找不到那个神秘的“系统设置”按钮?别急,今天...
安卓玩苹果系统吃鸡,揭秘跨界吃... 你知道吗?现在这个世界上,安卓手机的用户竟然也能享受到苹果系统的乐趣,而且还能畅玩《绝地求生》这款热...
安卓系统好用的绘画软件,盘点几... 你有没有发现,手机上的绘画软件越来越多了?今天,我就要给你安利几款在安卓系统上超级好用的绘画软件,让...
海信哪款是安卓系统,海信安卓系... 你有没有想过,家里的电视、手机、电脑,哪个才是你最离不开的宝贝?对我来说,那当然是非手机莫属啦!不过...
安卓手机rom系统分区,分区布... 你有没有发现,你的安卓手机最近有点儿“闹腾”?运行速度不如以前流畅,有时候还突然卡壳,是不是觉得它有...
给苹果手机刷安卓系统,探索刷安... 你有没有想过给你的苹果手机来个“换装大法”?没错,就是给苹果手机刷上安卓系统!听起来是不是有点不可思...
美版安卓手机更新系统,全新功能... 你有没有发现,最近你的美版安卓手机更新系统后,感觉整个操作界面都焕然一新了呢?这不,今天就来给你详细...