Java并发中倒计时锁实例的实践
我正在阅读Java并发性实践手册,遇到了倒计时锁 以下是给出的示例:Java并发中倒计时锁实例的实践,java,multithreading,concurrency,Java,Multithreading,Concurrency,我正在阅读Java并发性实践手册,遇到了倒计时锁 以下是给出的示例: public class TestHarness { public long timeTasks(int nThreads, final Runnable task) throws InterruptedException { final CountDownLatch startGate = new CountDownLatch(1); final CountDownL
public class TestHarness {
public long timeTasks(int nThreads, final Runnable task)
throws InterruptedException {
final CountDownLatch startGate = new CountDownLatch(1);
final CountDownLatch endGate = new CountDownLatch(nThreads);
for (int i = 0; i < nThreads; i++) {
Thread t = new Thread() {
public void run() {
try {
startGate.await();
try {
task.run();
} finally {
endGate.countDown();
}
} catch (InterruptedException ignored) { }
}
};
t.start();
}
long start = System.nanoTime();
startGate.countDown();
endGate.await();
long end = System.nanoTime();
return end-start;
}
}
及
请帮助我理解这个概念。这段代码
Thread t = new Thread() {
public void run() {
try {
startGate.await();
try {
task.run();
} finally {
endGate.countDown();
}
} catch (InterruptedException ignored) { }
}
};
设置所需的所有线程。每个线程将等待startGate
被“打开”,即其计数变为0。当线程执行完Runnable
,即run()
返回时,它们将对endGate
进行倒计时。这就是为什么
每个工作线程所做的第一件事是等待启动门;
这确保了它们在全部准备就绪之前都不会开始工作
开始。每个人做的最后一件事是在终点门上倒计时
意味着
设置所有线程后,将执行此代码
long start = System.nanoTime();
startGate.countDown();
endGate.await();
long end = System.nanoTime();
return end-start;
当前线程倒计时startGate
,这允许所有其他线程开始执行其Runnable
,即task.run()
。然后等待端门上的(块)倒计时到0。在这一点上,它会计算花费的时间并返回该值。这就是为什么
这允许主线程高效地等待,直到最后一个
工作线程已完成,因此它可以计算经过的时间
意思是只要不清楚您已经知道了什么,实际上并不完全清楚您的实际问题是什么,或者代码应该如何解释
但是,此处使用的概念并不复杂,通过删除错误处理并用内嵌注释指出重要部分,可能已经变得更加清晰:
for (int i = 0; i < nThreads; i++) {
// This will create and start a new thread
// that executes the code in the "run" method
Thread t = new Thread() {
public void run() {
// Wait until this thread gets the start signal
startGate.await();
// Perform some arbitrary work
task.run();
// Notify everybody that this thread has finished his work
endGate.countDown();
}
};
t.start();
}
// Give all threads the start signal: Counting down
// where will cause the latch to reach the value 0,
// and every thread that is waiting at "startGate.await()"
// will proceed his work
startGate.countDown();
// Wait here until all threads have called "endGate.countDown()".
endGate.await();
for(inti=0;i
开始日期最初设置为1,因此所有线程将等待,直到倒计时
endGate
被初始化为我们计划使用的线程数,因此它将等待所有线程通过endGate,然后报告所用的时间
// Take a note of the time.
long start = System.nanoTime();
// Start all of the threads running - they all wait for this signal by calling startGate.await().
startGate.countDown();
// Wait for all threads to complete - they record their finish with endGate.countDown().
endGate.await();
// Note the time.
long end = System.nanoTime();
package com.sample.thread;
导入java.util.concurrent.CountDownLatch;
公共类CDLExample{
专用静态倒计时锁存器;
公共静态void main(字符串参数[]){
闩锁=新的倒计时闩锁(2);
新线程(“主线程”){
公开募捐{
试一试{
satch.wait();
系统输出
.println(“\n在启动所有其他线程时启动主线程”);
System.out.println(“倒计时锁存器:
+Thread.currentThread().getName());
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}.start();
新线程(“第一个”){
公开募捐{
System.out.println(“打印奇数:”
+Thread.currentThread().getName());
试一试{
对于(int i=1;i<20;i=i+2){
系统输出打印(i+“”);
睡眠(50);
}
}捕捉(中断异常e){
e、 printStackTrace();
}
倒计时();
}
}.start();
新线程(“第二个”){
公开募捐{
试一试{
睡眠(1000);
System.out.println(“\n打印偶数:”
+Thread.currentThread().getName());
对于(int i=2;i<20;i=i+2){
睡眠(50);
系统输出打印(i+“”);
}
}捕捉(中断异常e){
e、 printStackTrace();
}
倒计时();
}
}.start();
}
}如果您不知道多线程是如何工作的,为什么要从倒数锁存开始呢?放慢速度。开始。@SotiriosDelimanolis,我正在用这本书学习多线程的概念,因为这是so中许多专家的建议。但是我在理解这个例子时遇到了困难。这本书不应该被用作多线程的介绍,因为你可以在本书的“如何使用”一节中清楚地读到。同一部分列出了建议的介绍性来源。启动线程需要时间。因此,如果每个线程一启动就执行它的任务,那么一些线程可能已经在运行,而另一些线程可能还没有创建。所以他们使用锁存器等待,直到主线程发出启动信号。就像在一场真正的赛跑中一样。当他们完成任务时,他们会发出信号,以便主线可以知道所有的马何时都完成了。想象一下赛马,当所有的马都在起跑线上时比赛才开始,直到最后一匹马到达终点线时比赛才结束。
for (int i = 0; i < nThreads; i++) {
// This will create and start a new thread
// that executes the code in the "run" method
Thread t = new Thread() {
public void run() {
// Wait until this thread gets the start signal
startGate.await();
// Perform some arbitrary work
task.run();
// Notify everybody that this thread has finished his work
endGate.countDown();
}
};
t.start();
}
// Give all threads the start signal: Counting down
// where will cause the latch to reach the value 0,
// and every thread that is waiting at "startGate.await()"
// will proceed his work
startGate.countDown();
// Wait here until all threads have called "endGate.countDown()".
endGate.await();
// Take a note of the time.
long start = System.nanoTime();
// Start all of the threads running - they all wait for this signal by calling startGate.await().
startGate.countDown();
// Wait for all threads to complete - they record their finish with endGate.countDown().
endGate.await();
// Note the time.
long end = System.nanoTime();
package com.sample.thread;
import java.util.concurrent.CountDownLatch;
public class CDLExample {
private static CountDownLatch latch;
public static void main(String args[]) {
latch = new CountDownLatch(2);
new Thread("main") {
public void run() {
try {
latch.await();
System.out
.println("\nStarting Main thread as all other thread is started");
System.out.println("CountDownLatch demonstrated: "
+ Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
new Thread("first") {
public void run() {
System.out.println("Print Odd Number: "
+ Thread.currentThread().getName());
try {
for (int i = 1; i < 20; i = i + 2) {
System.out.print(i + " ");
Thread.sleep(50);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
}
}.start();
new Thread("second") {
public void run() {
try {
Thread.sleep(1000);
System.out.println("\nPrint Even Number: "
+ Thread.currentThread().getName());
for (int i = 2; i < 20; i = i + 2) {
Thread.sleep(50);
System.out.print(i + " ");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
}
}.start();
}