为什么要引入Executor:
1)按照传统的方式,每次new Thread创建就一个对象,对象的创建和销毁是耗费资源的;
2)每次new Thread创建的线程缺乏管理,线程之间相互竞争,占用过多的资源,严重的还会导致瘫痪;
3)不利于扩展,比如定时执行、定期执行、线程中断。
Executor的作用:为你管理Thread对象,从而简化并发编程
1)Executor允许你管理异步任务的执行而无需显式地管理线程的生命周期;
2)能够实现对现存线程重用,减少对象创建和销毁耗费的资源;
3)有利于扩展,比如实现定时执行、定期执行、线程中断。
4)控制最大并发线程数,避免过多资源相互竞争
先建立一个继承Runnable的类
class LiftOff implements Runnable{
protected int countDown = 10;
private static int taskCount = 0; //实例化对象计数
private final int id = taskCount++;
public LiftOff() {};
public LiftOff(int countDown) {
this.countDown = countDown;
}
public String status() {
return "#"+id+"("+(countDown>0?countDown:"LiftOff!")+")";
}
@Override
public void run() {
while(countDown-->0) {
System.out.println(status());
Thread.yield();
}
}
}
在MainThread中使用Executor
1.使用CachedThreadPool
public class MainThread{
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
for(int i=0 ; i<5 ; i++) {
exec.execute(new LiftOff());
}
exec.shutdown();
}
}
2.使用FixedThreadPool--可以控制线程的数量
public class MainThread{
public static void main(String[] args) {
ExecutorService exec = Executors.newFixedThreadPool(5);
for(int i=0 ; i<5 ; i++) {
exec.execute(new LiftOff());
}
exec.shutdown();
}
}
3.使用SingleThreadExecutor--单线程的线程池,可以序列化地执行提交的多个任务
public class MainThread{
public static void main(String[] args) {
ExecutorService exec = Executors.newSingleThreadExecutor();
for(int i=0 ; i<5 ; i++) {
exec.execute(new LiftOff());
}
exec.shutdown();
}
}
使用SingleThreadExecutor的执行结果
#0(9)
#0(8)
#0(7)
#0(6)
#0(5)
#0(4)
#0(3)
#0(2)
#0(1)
#0(LiftOff!)
#1(9)
#1(8)
#1(7)
#1(6)
#1(5)
#1(4)
#1(3)
#1(2)
#1(1)
#1(LiftOff!)
#2(9)
#2(8)
#2(7)
#2(6)
#2(5)
#2(4)
#2(3)
#2(2)
#2(1)
#2(LiftOff!)
#3(9)
#3(8)
#3(7)
#3(6)
#3(5)
#3(4)
#3(3)
#3(2)
#3(1)
#3(LiftOff!)
#4(9)
#4(8)
#4(7)
#4(6)
#4(5)
#4(4)
#4(3)
#4(2)
#4(1)
#4(LiftOff!)