如下代码所示,我们按照顺序写了一段多线程的代码,然后想让t1,t2,t3都能顺序的执行
/** * 没有顺序执行的示例 */ public static void test() { Thread t1 = new Thread(() -> { System.out.println("1"); }, "t1"); Thread t2 = new Thread(() -> { System.out.println("2"); }, "t2"); Thread t3 = new Thread(() -> { System.out.println("3"); }, "t3"); t1.start(); t2.start(); t3.start(); }
但是运行后,它并不是按照顺序执行的,如下:
1
3
2
如何才能保证顺序执行呢?
方法一:
使用Join
jion的意思是加入线程,需要等待线程执行完毕以后,其它线程才能够继续执行
代码演示:
public static void test2() throws InterruptedException { Thread t1 = new Thread(() -> { System.out.println("1"); }, "t1"); Thread t2 = new Thread(() -> { System.out.println("2"); }, "t2"); Thread t3 = new Thread(() -> { System.out.println("3"); }, "t3"); t1.start(); t1.join(); t2.start(); t2.join(); t3.start(); t3.join(); }
运行结果:
1
2
3
主要利用了join的阻塞效果(阻塞主线程),来达到我们的使用目的。
方式二:利用Executors线程池
Executors是JUC里面的操作类,可以方便的给我们提供线程池的操作,这里我们使用Executors中的newSingleThreadExecutor方法,创建一个单线程的线程池。
/** * 使用线程池 */ public static void test3() { // 创建一个单例线程 ExecutorService executorService = Executors.newSingleThreadExecutor(); Thread t1 = new Thread(() -> { System.out.println("1"); }, "t1"); Thread t2 = new Thread(() -> { System.out.println("2"); }, "t2"); Thread t3 = new Thread(() -> { System.out.println("3"); }, "t3"); executorService.submit(t1); executorService.submit(t2); executorService.submit(t3); }
运行结果:
1
2
3
这里主要就是利用了newSingleThreadExecutor()方法,其实原理很简单,因为单例线程池的内部是一个基于FIFO的队列,也就是说当我们依次将t1, t2, t3加入队列中,实际上就绪状态只有t1这个线程,t2,t3则会被添加到队列中,当t1执行完毕后,在从队列中获取一个放到就绪队列。