newSingleThreadExecutor 这个线程池,保证线程里面的任务依次执行,这让我发现了新大陆,
立马实践了一下,发现不负所望;
public class TestJoin {
public static void main(String[] args) throws InterruptedException {
final Thread t1 = new Thread(new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getName() + " run 1");
}
}, "T1");
final Thread t2 = new Thread(new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getName() + " run 2");
try {
t1.join(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "T2");
final Thread t3 = new Thread(new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getName() + " run 3");
try {
t2.join(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "T3");
// method1 第一反应的解决方法,事实证明不可靠
//t1.start();
//t2.start();
//t3.start();
// method 2 使用 单个任务的线程池来实现。保证线程的依次执行
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(t1);
executor.submit(t2);
executor.submit(t3);
executor.shutdown();
}
}
在这里发现结果每次都是 t1执行,t2执行,t3执行,这里达到目的了之后,不禁回想,这个Single线程池为啥这么好用,不由得就像把线程池狠狠的看一遍,然后就去翻看了源代码
/**
* Creates an Executor that uses a single worker thread operating
* off an unbounded queue. (Note however that if this single
* thread terminates due to a failure during execution prior to
* shutdown, a new one will take its place if needed to execute
* subsequent tasks.) Tasks are guaranteed to execute
* sequentially, and no more than one task will be active at any
* given time. Unlike the otherwise equivalent
* {@code newFixedThreadPool(1)} the returned executor is
* guaranteed not to be reconfigurable to use additional threads.
*
* @return the newly created single-threaded Executor
*/
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
这个实例化的意思我尝试翻译了一下,意思就是创建一个只有一个线程的线程池来操作不限数量的队列,也就是把线程放进了一个队列中,队列我们都知道是FIFO的(LinkedBlockingQueue)。SingleThreadExecutor的工作线程只有一个,其他队列中的线程都处于休眠,也就是sleep状态,当这个worker线程做完事了,也就是run方法运行结束,就又从队列中拿出一个休眠线程(sleep)出来唤醒(notify),这样依次把队列中的所有线程处理完毕,这样并没有结束,如果线程池中没有待处理的线程,线程池一直会等待,等待下一次任务的提交,除非把线程池给shutdown掉,这样线程池的生命周期才算完毕。