基础使用
CountDownLatch类的应用场景 : 主要是用于当前线程等待其他线程完成之后再继续完成,和join()有相同的作用。
实现代码如下:
public class Sample_Thread extends Thread {
private CountDownLatch latch;
public Sample_Thread(CountDownLatch latch) {
this.latch = latch;
}
@Override
public void run() {
try {
Thread.sleep(2000);
System.out.println("线程已完成");
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
测试类:
public class Test {
public static void main(String[] args) {
try {
CountDownLatch latch=new CountDownLatch(2);
Sample_Thread t1 = new Sample_Thread(latch);
Sample_Thread t2 = new Sample_Thread(latch);
Sample_Thread t3 = new Sample_Thread(latch);
t1.start();
t2.start();
latch.await();
System.out.println("前两个线程已完成");
t3.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
运行如下:
可以发现是主线程在latch.await();
之后等待两个线程已经完成之后才继续执行。
如果使用join() 方法来实现这个作用:
只需要修改Test类:
public class Test {
public static void main(String[] args) {
try {
CountDownLatch latch=new CountDownLatch(2);
Sample_Thread t1 = new Sample_Thread(latch);
Sample_Thread t2 = new Sample_Thread(latch);
Sample_Thread t3 = new Sample_Thread(latch);
t1.start();
t2.start();
// latch.await();
t1.join();
t2.join();
System.out.println("前两个线程已完成");
t3.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
join()和CountDownLatch的区别
既然两者都可以实现相同的功能,但是也有区别。
可以发现,我们在线程内部使用latch.countDown();来使CountDownLatch的计数减少一,如果我们把这条语句放到线程中间的话,就会和join()方法产生区别:
修改线程类:
public class Sample_Thread extends Thread {
private CountDownLatch latch;
public Sample_Thread(CountDownLatch latch) {
this.latch = latch;
}
@Override
public void run() {
try {
Thread.sleep(2000);
System.out.println("线程完成一半");
latch.countDown();
Thread.sleep(1000);
System.out.println("线程已完成");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
测试类还是使用await() ,此时测试结果如下:
发现,主线程在前两个线程都未完成的情况下就已经继续向下执行了,但是这在使用join()的情况下还是不变: