我以前在甲骨文博客上练习过这个问题,我有一个问题,就是如何在CyclicBarrier中获得/访问一个屏障动作的输出。
博客链接
代码
public class CBTest {
private List<Integer> results = Collections.synchronizedList(new ArrayList<>());
class Calculator extends Thread {
CyclicBarrier cb;
int param;
public Calculator(CyclicBarrier cb, int param) {
this.cb = cb;
this.param = param;
}
public void run() {
try {
results.add(param);
System.out.println("going to await");
cb.await();
} catch (InterruptedException | BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
void doCalculation() {
CyclicBarrier cb = new CyclicBarrier(2, () -> {
var ans = results.stream().mapToInt(v -> v.intValue()).sum();
System.out.println("ANS IS "+ans);
});
new Calculator(cb, 2).start();
new Calculator(cb, 3).start();
}
public static void main(String[] args) {
var test = new CBTest();
test.doCalculation();
}
}请让我知道如何在主要方法中获得循环阻隔作用ans的值?
发布于 2021-11-25 00:48:44
可以通过使用附加的doCalculation (CountDownLatch)来同步生成doCalculation返回结果,在这种情况下,doCalculation方法将被阻塞,直到生成计算结果:
CountDownLatch countDownLatch = new CountDownLatch(1);
int doCalculation() throws InterruptedException {
AtomicInteger result = new AtomicInteger();
CyclicBarrier cb = new CyclicBarrier(2, () -> {
result.set(results.stream().mapToInt(v -> v.intValue()).sum());
// count down
countDownLatch.countDown();
});
new Calculator(cb, 2).start();
new Calculator(cb, 3).start();
// block util it is countDown.
countDownLatch.await();
return result.get();
}
public static void main(String[] args) throws InterruptedException {
var test = new CBTest();
System.out.println("ANS IS " + test.doCalculation());
}发布于 2021-11-24 17:11:41
因为CyclicBarrier只接受一个Runnable,所以它不返回值。因此,您需要在外部定义的输出容器中设置结果--可能是AtomicReference作为CBTest中的字段。然后,Runnable可以将值设置为它。
这是一个略有改变的版本,我的更改标记为注释CHANGE。
public class CBTest{
private List<Integer> results = Collections.synchronizedList( new ArrayList<>() );
/* CHANGE: Value holder. Could be another thread-safe class. */
private AtomicReference<Integer> answer = new AtomicReference<>( 0 );
class Calculator extends Thread{
CyclicBarrier cb;
int param;
public Calculator( CyclicBarrier cb, int param ){
this.cb = cb;
this.param = param;
}
public void run(){
try{
results.add( param );
System.out.println( "going to await" );
cb.await();
/* CHANGE: Both threads get the same value. */
System.out.println( answer.get() );
}
catch( InterruptedException | BrokenBarrierException e ){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
void doCalculation(){
CyclicBarrier cb = new CyclicBarrier( 2, () -> {
var ans = results.stream().mapToInt( v -> v.intValue() ).sum();
System.out.println( "ANS IS " + ans );
/* CHANGE: Set the value here. */
answer.set( ans );
} );
new Calculator( cb, 2 ).start();
new Calculator( cb, 3 ).start();
}
public static void main( String[] args ){
var test = new CBTest();
test.doCalculation();
}
}https://stackoverflow.com/questions/70097285
复制相似问题