九又四分之三站台

0%

线程按指定顺序执行

在多线程中线程的执行是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();

}