[英]Wait till first method is executed in all threads till execute second
我有一个小的演示代码,其中有一个 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()
。 任何想法如何以正确的方式做到这一点?
您可以使用跨所有线程共享的CountDownLatch
。
首先是一些理论:什么是CountDownLatch ?
这是一个非常简单的并发实用程序,您可以使用某个整数(假设为 N)进行初始化。然后它为您提供了两种方法:
countdown()
=> 每次调用它都会减少到N-1
await()
=> 它将停止当前线程,直到倒计时计数为零(如果需要,您可以指定超时)。 当然,这个类的最大优点是可以为您处理竞争条件(当您从某个线程调用countdown()
或await()
时,可以保证其他线程将看到正在发生的事情,而无需您处理任何内存屏障) .
所以现在,根据您的代码,您首先让Bean
的preInit
和postInit
方法采用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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.