Java 用于同步的CyclicBarrier与Countdownlock
我读过Bloch的第69项(有效Java),其中有一个简单的定时执行框架示例,它使用3Java 用于同步的CyclicBarrier与Countdownlock,java,multithreading,Java,Multithreading,我读过Bloch的第69项(有效Java),其中有一个简单的定时执行框架示例,它使用3CountDownLatch进行同步线程。布洛赫还说,这个例子可以用1CyclicBarrier重写。我已尝试执行此操作并获取下一个代码: public static long time(ExecutorService exec, int count) throws InterruptedException, BrokenBarrierException { CyclicBar
CountDownLatch
进行同步线程。布洛赫还说,这个例子可以用1CyclicBarrier
重写。我已尝试执行此操作并获取下一个代码:
public static long time(ExecutorService exec, int count) throws InterruptedException, BrokenBarrierException {
CyclicBarrier cyclicBarrier = new CyclicBarrier(count+1);
for (int i = 0; i < count; i++) {
exec.submit(new Worker(cyclicBarrier, i));
}
System.out.println("Start processing");
cyclicBarrier.await();
long time = System.nanoTime();
cyclicBarrier.await();
long elapsedTime = (System.nanoTime() - time)/1000;
System.out.println("FIN. ");
return elapsedTime;
}
private static class Worker implements Runnable {
final CyclicBarrier cyclicBarrier;
int workerNumber;
Worker(CyclicBarrier cyclicBarrier, int workerCount) {
this.cyclicBarrier = cyclicBarrier;
this.workerNumber = workerCount;
}
public void run() {
try {
cyclicBarrier.await();
work();
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
private void work() {
System.out.println("Worker " + workerNumber + " starts his job");
System.out.println("Worker " + workerNumber + " finishes his job");
}
}
publicstaticlongtime(ExecutorService exec,int count)抛出InterruptedException、BrokenBarrierException{
CyclicBarrier CyclicBarrier=新的CyclicBarrier(计数+1);
for(int i=0;i
但我认为这里有一个问题(在time
方法中):在第一次wait
之后,我尝试测量线程执行的开始时间,所以我想在所有其他线程开始之前测量这个时间。无法保证此(long time=System.nanoTime();
)指令将在另一个线程启动之前执行
如何使用CyclicBarrier实现这些功能?任何建议?
CyclicBarrier
允许您定义一个屏障操作,该操作将在所有线程到达屏障后但在它们恢复执行之前执行。使用CyclicBarrier(int,Runnable)
来定义它
显然,在您的情况下,您需要在工作之前和完成之后区分屏障动作的执行情况,如下所示:
class TimingAction implements Runnable {
private boolean running;
private long start;
private long elapsed;
public void run() {
if (running) {
elapsed = System.nanoTime() - start;
running = false;
} else {
start = System.nanoTime();
running = true;
}
}
...
}
TimingAction timer = new TimingAction();
CyclicBarrier cyclicBarrier = new CyclicBarrier(count + 1, timer);
...
long elapsed = timer.getElapsed();
伟大的解决方案!谢谢我最近还了解到,我可以创建一个holder类(又名mutable Long),并直接在CyclicBarrier的匿名Runnable中使用它