在多线程中线程的执行是CPU随机调度的,无法指定线程的执行顺序,比如我们要让多线程按顺序执行输出
1 2 3 4 5 6 7
| Thread thread1 = new Thread(() -> System.out.println(Thread.currentThread().getName()), "thread1"); Thread thread2 = new Thread(() -> System.out.println(Thread.currentThread().getName()), "thread2"); Thread thread3 = new Thread(() -> System.out.println(Thread.currentThread().getName()), "thread3");
thread1.start(); thread2.start(); thread3.start();
|
这段代码的输出顺序是未知的,可能是123,可能是213也可能是其它情况,我们无法保证哪一个线程会最先执行
这种情况下要保证顺序输出就要求Thread2在Thread1结束后执行,Thread3在Thread2完成后执行
使用Thread的join()方法
1 2 3 4 5 6 7 8 9 10 11 12 13
| public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(() -> System.out.println(Thread.currentThread().getName()), "thread1"); Thread thread2 = new Thread(() -> System.out.println(Thread.currentThread().getName()), "thread2"); Thread thread3 = new Thread(() -> System.out.println(Thread.currentThread().getName()), "thread3");
thread1.start(); thread1.join(); thread2.start(); thread2.join(); thread3.start();
}
|
join方法会阻塞直到该线程执行结束
来看一下Thread类内部的join()方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| public final void join() throws InterruptedException { join(0); }
public final synchronized void join(long millis) throws InterruptedException { long base = System.currentTimeMillis(); long now = 0;
if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); }
if (millis == 0) { while (isAlive()) { wait(0); } } else { while (isAlive()) { long delay = millis - now; if (delay <= 0) { break; } wait(delay); now = System.currentTimeMillis() - base; } } }
|
当调用join()方法时,millis参数为0,表示当当前线程未结束时,会一直执行wait()方法阻塞主线程,wait()是native方法由其它语言实现
1
| public final native void wait(long timeout) throws InterruptedException;
|
当timeout参数为0时会无限期等待
使用单线程的线程池
1 2 3 4 5 6 7 8 9 10 11 12 13
| public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(() -> System.out.println("1")); Thread thread2 = new Thread(() -> System.out.println("2")); Thread thread3 = new Thread(() -> System.out.println("3"));
ExecutorService executorService = Executors.newSingleThreadExecutor(); executorService.submit(thread1); executorService.submit(thread2); executorService.submit(thread3); executorService.shutdown();
}
|