一般來說
多條執行緒會同步執行
例如以下程式碼
開了10個執行緒
藉著 print 追蹤執行順序
public class ThreadTest extends Thread {
public void run() {
System.out.println(getName() + " start");
try {
Thread.sleep((int) (Math.random() * 10000));
} catch (InterruptedException e) {
}
System.out.println(getName() + " end");
}
}
public class Demo {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
Thread t = new ThreadTest();
t.start();
}
}
可以看到開始與結束都是不可控的
如果某些業務需求
必須區分執行的先後順序
有三種解決辦法
一、join()
執行緒啟動後呼叫 join 方法
就會等待此執行緒先完成後
再執行其他動作
public class Demo {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
Thread t = new ThreadTest();
t.start();
try {
t.join();
} catch (InterruptedException e) {
}
}
}
}
二、wait()
呼叫 Object 的 wait 方法
注意必須 synchronized
否則會出 IllegalMonitorStateException
public class Demo {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
Thread t = new ThreadTest();
t.start();
try {
synchronized (t) {
t.wait();
}
} catch (InterruptedException e) {
}
}
}
}
三、CountDownLatch 物件
將 CountDownLatch 傳入執行緒
待全部執行完畢倒數
import java.util.concurrent.CountDownLatch;
public class ThreadTest extends Thread {
CountDownLatch countDownLatch;
public ThreadTest(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
public void run() {
System.out.println(getName() + " start");
try {
Thread.sleep((int) (Math.random() * 10000));
} catch (InterruptedException e) {
}
System.out.println(getName() + " end");
countDownLatch.countDown();
}
}
設置計數器
倒數至 0 才會執行其他動作
import java.util.concurrent.CountDownLatch;
public class Demo {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
CountDownLatch countDownLatch = new CountDownLatch(1);
Thread t = new ThreadTest(countDownLatch);
t.start();
try {
countDownLatch.await();
} catch (InterruptedException e) {
}
}
}
}
結果: