以前项目中没用到过线程池,今天偶然有人问起就研究了下:
首先在JDK6.0中提供了线程池的方法:
ThreadPoolExecutor类
一个 ExecutorService
,它使用可能的几个池线程之一执行每个提交的任务,通常使用 Executors
工厂方法配置。
线程池可以解决两个不同问题:由于减少了每个任务调用的开销,它们通常可以在执行大量异步任务时提供增强的性能,并且还可以提供绑定和管理资源(包括执行任务集时使用的线程)的方法。每个 ThreadPoolExecutor 还维护着一些基本的统计数据,如完成的任务数。
为了便于跨大量上下文使用,此类提供了很多可调整的参数和扩展钩子 (hook)。但是,强烈建议程序员使用较为方便的 Executors
工厂方法Executors.newCachedThreadPool()
(无界线程池,可以进行自动线程回收)、Executors.newFixedThreadPool(int)
(固定大小线程池)和Executors.newSingleThreadExecutor()
(单个后台线程),它们均为大多数使用场景预定义了设置。
使用ExecutorService threadPool=Executors.newCachedThreadPool();实现线程池
1.新建一个线程方法:
package com.dava; import java.util.Random; public class MyThread extends Thread {
//标记运行的是哪个线程 private int i; public MyThread(int i) { this.i = i; } @Override public void run() { System.out.println("线程开始执行..." + i); try { //线程处理时,暂停 sleep(new Random().nextInt(1000)); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("线程结束执行..." + i); } }
2.调用线程
package com.dava; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadPoolExecutor; public class ThreadRun{ public static void main(String[] args) { //线程池 ExecutorService threadPool=Executors.newCachedThreadPool(); MyThread mt1=new MyThread(1); MyThread mt2=new MyThread(2); MyThread mt3=new MyThread(3); MyThread mt4=new MyThread(4); MyThread mt5=new MyThread(5); MyThread mt6=new MyThread(6); MyThread mt7=new MyThread(7); MyThread mt8=new MyThread(8); MyThread mt9=new MyThread(9); MyThread mt10=new MyThread(10); threadPool.execute(mt1); threadPool.execute(mt2); threadPool.execute(mt3); threadPool.execute(mt4); threadPool.execute(mt5); threadPool.execute(mt6); threadPool.execute(mt7); threadPool.execute(mt8); threadPool.execute(mt9); threadPool.execute(mt10);
threadPool.shutdown(); } }
运行结果:
线程开始执行...4 线程开始执行...3 线程开始执行...5 线程开始执行...1 线程开始执行...2 线程开始执行...7 线程开始执行...6 线程开始执行...8 线程开始执行...9 线程开始执行...10 线程结束执行...7 线程结束执行...4 线程结束执行...10 线程结束执行...2 线程结束执行...6 线程结束执行...3 线程结束执行...9 线程结束执行...1 线程结束执行...8 线程结束执行...5
每个线程等待随机时间,用于判断线程任务所需时间。
如何统计线程某一个时刻完成数目呢?
可以使用如下方法:
((ThreadPoolExecutor) threadPool).getCompletedTaskCount()
整体方法为:
package com.dava; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadPoolExecutor; public class ThreadRun{ public static void main(String[] args) { //线程池 ExecutorService threadPool=Executors.newCachedThreadPool(); MyThread mt1=new MyThread(1); MyThread mt2=new MyThread(2); MyThread mt3=new MyThread(3); MyThread mt4=new MyThread(4); MyThread mt5=new MyThread(5); MyThread mt6=new MyThread(6); MyThread mt7=new MyThread(7); MyThread mt8=new MyThread(8); MyThread mt9=new MyThread(9); MyThread mt10=new MyThread(10); threadPool.execute(mt1); threadPool.execute(mt2); threadPool.execute(mt3); threadPool.execute(mt4); threadPool.execute(mt5); threadPool.execute(mt6); threadPool.execute(mt7); threadPool.execute(mt8); threadPool.execute(mt9); threadPool.execute(mt10); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(((ThreadPoolExecutor) threadPool).getCompletedTaskCount()); threadPool.shutdown(); } }
运行结果为:
线程开始执行...2 线程开始执行...6 线程开始执行...10 线程开始执行...1 线程开始执行...3 线程开始执行...4 线程开始执行...5 线程开始执行...7 线程开始执行...8 线程开始执行...9 线程结束执行...1 1 线程结束执行...3 线程结束执行...10 线程结束执行...9 线程结束执行...5 线程结束执行...6 线程结束执行...2 线程结束执行...7 线程结束执行...8 线程结束执行...4
end;
一步一步行走,做好每一件事情。