先看一个图来简单了解一下线程池的工作流程
1.线程池创建的Thread对象,run方法会通过阻塞队列的take方法获取一个Runnable对象
2.当需要向线程池提交任务时会调用阻塞队列的offer方法向队列的尾部添加任务。
3.当Runnable对象的run方法执行完毕以后,Thread中的run方法又循环的从阻塞队列中获取下一个Runnable对象继续执行。
这样就实现了Thread对象的重复利用,也就减少了创建线程和销毁线程所消耗的资源。
我们再看一个例子
public class MyClass {
public static void main(String[] args) {
ExecutorService threadPool = Executors.newFixedThreadPool(3);//线程池中,3工作线程
threadPool.execute(new ThreadPoolDemo.Task("a"));
threadPool.execute(new ThreadPoolDemo.Task("b"));
threadPool.execute(new ThreadPoolDemo.Task("c"));
threadPool.execute(new ThreadPoolDemo.Task("d"));
threadPool.execute(new ThreadPoolDemo.Task("e"));
threadPool.shutdown();
System.out.println(threadPool.isShutdown());//是否执行了shutdown
System.out.println(threadPool.isTerminated());//是否执行完所有的任务
while(!threadPool.isTerminated()){
//阻塞
}
System.out.println("OVER");
}
}
class ThreadPoolDemo {
static class Task implements Runnable {
private String id;
Task(String id) {
this.id = id;
}
@Override
public void run() {
System.out.println("Thread " + id + " is run");
try {
//每个任务随机延时1s以内的时间以模拟线程的运行
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread " + id + " run over");
}
}
}
执行结果
Thread b is run
Thread a is run
Thread c is run
true
false
Thread c run over
Thread d is run
Thread b run over
Thread e is run
Thread e run over
Thread d run over
Thread a run over
OVER
我们可以看到:
1.打印的方法isShutdown 和 isTerminated 分别是true 和 false,isShutdown表示是否执行了shutdown,而isTerminated 指是否执行完成所有的任务
2.线程池中固定只允许同时执行的数量为3个,所以必须前3个执行完至少一个后面的等待线程才能执行
3.因为线程是并发执行的,所以顺序是乱序的,如果想顺序可以把newFixedThreadPool(3)改为1,或者使用newSingleThreadExecutor。