当前位置: 首页 > news >正文

线程池的应用-->2

1.自定义线程工程

  • 当需要自定义线程的名字,线程的优先级,精灵线程状态时,需要自定义线程工厂。

  • 如何自定义线程工厂

    1. 自定义工厂类,实现ThreadFactory接口,重写方法newThread()

    2. 在创建线程池对象时,传递上述线程工厂对象

public class Test5 {public static void main(String[] args) {System.out.println("------------------------");ThreadPoolExecutor pool = new ThreadPoolExecutor(5,15,5, TimeUnit.SECONDS,new ArrayBlockingQueue<>(5),new MyThreadFactory());pool.execute(()->{System.out.println("---->"+Thread.currentThread().getName());});}
}class MyThreadFactory implements ThreadFactory{//int count = 1 ;AtomicInteger count = new AtomicInteger(1);@Overridepublic Thread newThread(Runnable r) {Thread t = new Thread(r);t.setName("pool-a-thread-"+count.getAndIncrement());t.setPriority(8);//t.setDaemon(true);return t;}
}

2.自定义拒绝策略

实现,当前线程池能力不足时,交给另一个线程池来执行。

  1. 自定义拒绝策略类,

  2. 创建线程池对象时,传递自定义拒绝策略对象

3.自动获得线程池

提供了5个方法可以快速获得线程池对象

//适合任务量大,功能简单的任务,需要确保每一次任务都需要快速反应
ExecutorService pool = Executors.newCachedThreadPool();//线程池中只有一个线程,确保任务顺序执行
//当内部的线程执行任务出错时,会创建一个新线程。
ExecutorService pool = Executors.newSingleThreadExecutor();//线程池内装载固定数量的线程
ExecutorService pool = Executors.newFixedThreadPool(5);//可以执行定时任务的线程池
ScheduledExecutorService pool = Executors.newScheduledThreadPool(1);//工作窃取线程池
//1. 本质是ForkJoinPool
//2. 提供了2个重载构造器,一个传参指定内部线程的数量,第二个不传参默认是逻辑处理器的数量
//3. 工作窃取线程池的机制
//	 所有的线程都是精灵线程
//	 之前的线程池,无论有多少个线程,都只有一个任务队列
//	 当一瞬间有多个线程同时完成任务时,就会同时去队列中获得新任务,此时就会发生阻塞(性能低)
//	 工作窃取线程池内部,每一个线程都配有一个任务队列,当完成任务时,去自己的队列中获取新任务
//	 当自己的队列中的任务完成后,就去其他线程任务队列中"窃取"任务执行
//	 每一个队列都是双端队列,当前线程从a端获取任务,其他线程从b端窃取任务
ExecutorService pool = Executors.newWorkStealingPool();
//延迟指定时间执行
//
pool.schedule(()->{System.out.println("-----------------------------");
},5, TimeUnit.SECONDS);//延迟指定时间,开始执行
//执行后,每隔指定时间,重复执行
//每次执行的时间 会与 间隔时间叠加pool.scheduleAtFixedRate(()->{for(int i = 1 ;i<=2;i++){System.out.println(i);try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}},5,2,TimeUnit.SECONDS);//延迟指定时间,开始执行
//执行后,每隔指定时间,重复执行
//每次执行的时间 不会与 间隔时间叠加pool.scheduleWithFixedDelay(()->{for(int i = 1 ;i<=2;i++){System.out.println(i);try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}},5,2,TimeUnit.SECONDS);

4.线程池生命周期

线程的生命周期

创建 -> 就绪 -> 运行 -> 销毁

                            |

                         暂停

线程池生命周期

  • 运行状态 RUNNING

    状态切换:随着线程池对象的创建,就立刻进入运行状态

    状态效果:运行时的线程池,可以接收任务,处理任务,缓存任务

  • 关闭状态 SHUTDOWN

    状态切换:在运行状态时,调用pool.shutdown()方法

    状态效果:线程池不再接收新任务,但会执行完先有的任务及队列中的任务

  • 停止状态 STOP

    状态切换:运行时直接调用pool.shutdownNow()方法

    或处于shutdown状态的线程池完成了所有手头任务,自动进入stop状态

    状态效果:线程池不再接收新任务,清除队列中的任务,中断正在执行的任务

  • 整理状态 TIDYING

    状态切换:没有方法能直接切换到整理状态

    处于stop状态的线程池,完成了所有任务处理工作,自动调用terminated()

    状态效果:逻辑上就是整理,释放资源,类似于finally中做的事

  • 终结状态 TERMINATED

    状态切换:没有方法能直接切换到终结状态

    处于整理状态的线程池,执行完terminated方法,自动进入终结状态

    状态效果:完全关闭线程池

5.并发工具

5.1CountDownLatch类

  • 提供计数器,当所有的线程都执行完毕后,当前线程再执行。

  • 可以代替多线程中的join作用

CountDownLatch latch = new CountDownLatch(5);
latch.countDown() ;//计数器-1
latch.await();//等待计数器为0(阻塞)
public class Test9 {static int count = 0 ;public static void main(String[] args) throws InterruptedException {ThreadPoolExecutor pool = (ThreadPoolExecutor) Executors.newFixedThreadPool(5);CountDownLatch latch = new CountDownLatch(5);//循环5次,完成5个任务(通过5个线程)for(int i=0;i<5;i++){pool.execute(()->{try {Thread.sleep((int)((Math.random()*4+1)*1000));} catch (InterruptedException e) {throw new RuntimeException(e);}//每个任务对count累加1000次for(int j=0;j<1000;j++){count++ ;}System.out.println(Thread.currentThread().getName()+"执行完毕");latch.countDown();});}latch.await();System.out.println(count);}
}

5.2Semaphore类

  • 信号量

  • 提供一组信号量,每一个线程都可以申请信号量, 确保指定数量的线程同时执行。

  • 每一个线程执行完毕后,需要释放信号量

Semaphore s = new Semaphore(5);
s.acquire();
s.release();
public static void main(String[] args) {Semaphore s = new Semaphore(5);ThreadPoolExecutor pool = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);for(int i = 1;i<=10;i++) {pool.execute(()->{try {s.acquire();System.out.println(Thread.currentThread().getName()+"正在执行");Thread.sleep(5000);s.release();} catch (InterruptedException e) {throw new RuntimeException(e);}});}}


http://www.mrgr.cn/news/25363.html

相关文章:

  • 职场效率提升秘籍
  • 合成控制法SCM
  • CSS——盒子模型
  • 数据处理与统计分析篇-day02-Linux进阶
  • 山峰个数【python实现】
  • 未来工业,新质赋能!迈威通信邀您共赴智造盛宴
  • C++多态讲解
  • 「漏洞复现」SPIP porte_plume插件 远程代码执行漏洞(CVE-2024-7954)
  • 装杯 之 Linux 指令1
  • NPDP|在传统行业,怎么做好产品管理?有啥诀窍
  • 计算机专业选题推荐-基于Java的企业员工考勤小程序
  • 简单分享-获取.txt文件内数据 文件内数据逗号分隔 分隔符 C语言
  • FreeRTOS 项目剖析
  • 征稿啦!第 19 届「中国 Linux 内核开发者大会」重磅启动
  • C++——STL中的迭代器(Iterator)补充
  • 新品|瑞芯微RK3588工控机IPC8801适用AI算力、边缘计算、工业视觉
  • 1265:【例9.9】最长公共子序列 动态规划
  • 养宠浮毛严重怎么清理?希喂、范罗士、IAM宠物空气净化器真实测评
  • 企业私有云容器化架构运维实战
  • 看过来!2024 云栖大会操作系统技术 Workshop 怎么玩?