我有一個小的演示代碼,其中有一個 Bean 類和 BeanRegister 類。Bean 類有兩個方法,分別是preInit()和postInit()。而 BeanRegister 是一個以 Bean 類為欄位的執行緒類。這是我的代碼:
public static void main(String[] args) {
Bean beanA = new Bean();
BeanRegister beanRegister1 = new BeanRegister(beanA);
BeanRegister beanRegister2 = new BeanRegister(beanA);
beanRegister1.start();
beanRegister2.start();
}
private static class BeanRegister extends Thread {
private final Bean bean;
public BeanRegister(Bean bean) {
this.bean = bean;
}
@Override
public void run() {
try {
bean.preInit();
bean.postInit();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private static class Bean {
public void preInit() throws InterruptedException {
Thread.sleep(new Random().nextInt(1000) * 5);
System.out.println("PreInit " Thread.currentThread().getName());
}
public void postInit() throws InterruptedException {
System.out.println("PostInit " Thread.currentThread().getName());
}
}
我面臨的問題是鎖定。我想在這些執行緒中的方法執行未完成postInit()之前鎖定所有執行緒。preInit()所以,當所有執行緒完成執行時preInit(),我想允許執行緒執行postInit()。任何想法如何以正確的方式做到這一點?
uj5u.com熱心網友回復:
您可以使用CountDownLatch在所有執行緒之間共享的。
首先是一些理論:什么是CountDownLatch?
這是一個非常簡單的并發實用程式,您可以使用某個整數(假設為 N)進行初始化。然后它為您提供了兩種方法:
countdown()=> 它會減少到N-1每次被呼叫await()=> 它將停止當前執行緒,直到倒計時計數為零(如果愿意,您可以指定超時)。
當然,這個類的最大優點是可以為您處理競爭條件(當您呼叫countdown()或await()從某個執行緒呼叫時,您可以保證其他執行緒將看到正在發生的事情,而無需您處理任何記憶體屏障)。
所以現在,根據您的代碼,您首先制作preInit和postInit采用in 引數Bean的方法:CountDownLatch
private static class Bean {
public void preInit(CountDownLatch latch) throws InterruptedException {
Thread.sleep(new Random().nextInt(1000) * 5);
System.out.println("PreInit " Thread.currentThread().getName());
latch.countDown(); //<-- each time one preInit ends, decrease the countdown by 1
}
public void postInit(CountDownLatch latch) throws InterruptedException {
latch.await(); //<-- even if you're called here, wait until when the countdown is at zero before starting execution
System.out.println("PostInit " Thread.currentThread().getName());
}
}
具體來說,它preInit會倒計時,而它postInit會await在實際開始之前為零。
然后,在您的呼叫函式中,您創建一個new CountDownLatch(2)(2獨立執行緒的數量在哪里),您只需將其推入呼叫堆疊:
public static void main(String[] args) {
Bean beanA = new Bean();
CountDownLatch latch = new CountDownLatch(2);
BeanRegister beanRegister1 = new BeanRegister(beanA, latch);
BeanRegister beanRegister2 = new BeanRegister(beanA, latch);
beanRegister1.start();
beanRegister2.start();
}
private static class BeanRegister extends Thread {
private final Bean bean;
private final CountDownLatch latch;
public BeanRegister(Bean bean, CountDownLatch latch) {
this.bean = bean;
this.latch = latch;
}
@Override
public void run() {
try {
bean.preInit(latch);
bean.postInit(latch);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
樣本輸出:
PreInit Thread-1
PreInit Thread-0
PostInit Thread-1
PostInit Thread-0
Process finished with exit code 0
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/477428.html
