【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;}}}}
}

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

相关内容

热门资讯

安卓系统的经典铃声,唤醒回忆的... 你有没有发现,手机里那些熟悉的铃声,有时候就像老朋友一样,陪伴着我们度过了无数个日日夜夜?今天,就让...
鸿蒙系统还是安卓系统号,系统之... 你有没有想过,手机里的操作系统就像是我们的大脑,它决定了我们手机能做什么,不能做什么。现在,就让我们...
安卓系统装贝达,安卓系统下的贝... 你有没有想过,你的安卓手机装上贝达系统后,会有怎样的奇妙体验呢?想象你的手机瞬间变身,变得流畅无比,...
安卓系统沃尔沃音响设置,轻松享... 你有没有发现,自从你的安卓手机和沃尔沃音响完美结合后,开车时的音乐体验简直就像是在音乐厅里一样?没错...
米10系统基于安卓,基于安卓的... 你知道吗?最近手机圈里可是热闹非凡呢!小米10这款手机,自从发布以来就吸引了无数人的目光。而它所搭载...
命令安卓系统怎么卸载,安卓系统... 手机里装了太多不用的应用,是不是感觉手机都快要爆炸了?别急,今天就来教你怎么轻松卸载安卓系统中的应用...
安卓系统安装小学教材,安卓系统... 你有没有想过,手机里的安卓系统竟然能装上小学教材呢?没错,你没听错!在这个信息爆炸的时代,科技的发展...
华为安卓系统锁住了,揭秘锁屏背... 最近是不是发现你的华为手机有点儿“顽皮”了?它突然间变得神秘起来,屏幕上那个熟悉的安卓系统仿佛被施了...
安卓电脑改苹果系统,跨越平台的... 你有没有想过,把你的安卓电脑改头换面,变成一个优雅的苹果系统使用者呢?想象那流畅的界面,那独特的触控...
安卓系统怎么按后台,并在任务完... 你有没有遇到过这种情况:手机屏幕一黑,安卓系统就自动进入后台了?是不是觉得有点小郁闷,想要手动切换回...
2021年安卓系统ui,202... 你有没有发现,手机界面最近好像换了个模样?没错,2021年的安卓系统UI可是来了一场大变身呢!今天,...
安卓系统程序编写软件,打造个性... 你有没有想过,手机里的那些神奇应用是怎么诞生的呢?没错,就是那些让你在闲暇时光刷刷视频、在通勤路上玩...
自动开机安卓系统,智能生活新篇... 你有没有想过,当你的安卓手机在清晨的第一缕阳光照耀下自动开机,那种轻松自在的感觉?想象不用再手动解锁...
真我平板x安卓系统,畅享智能生... 亲爱的读者们,你是否也在寻找一款既能满足你对平板电脑的期待,又能让你畅享安卓系统带来的无限乐趣的设备...
恒星安卓系统官网,引领未来智能... 亲爱的读者们,你是否曾好奇过那些闪耀在夜空中的星星,它们是如何在浩瀚的宇宙中熠熠生辉的呢?今天,我要...
u8安卓系统,功能与特色深度解... 你知道吗?在手机操作系统界,有一个小家伙可是相当受欢迎的,它就是U8安卓系统。今天,就让我带你来一探...
花椒安卓系统美颜功能,打造完美... 你有没有发现,现在拍照已经不仅仅是记录生活的工具了,它更是一种艺术创作呢!而在这其中,花椒安卓系统的...
戴尔平板升级安卓系统,畅享安卓... 你有没有发现,戴尔平板最近好像悄悄地来了一次大变身?没错,就是那个我们熟悉的戴尔平板,它现在竟然可以...
安卓助手怎么升级系统,畅享最新... 亲爱的安卓用户们,你是否也和我一样,对安卓系统的升级充满了期待和好奇呢?每次系统升级,都仿佛是给我们...
国产安卓系统的发展,国产安卓系... 你知道吗?在我国科技飞速发展的今天,国产安卓系统可是越来越受到大家的关注呢!它就像一颗冉冉升起的新星...