前序:
上周测试给开发的同事所开发的模块提出了一个 bug,并且还是偶现.
经过仔细查看代码,发现是在业务中启用了多线程,2 个线程同时跑,但是新启动的 2 个线程必须保证一个完成之后另一个再继续运行,才能消除 bug.
什么时候用?
多线程是在很多地方都会用到的,但是我们如果想要实现在某个特定的线程运行完之后,再启动另外一个线程呢,这个时候 CountDownLatch 就可以派上用场了
怎么用?
先看看普通的多线程代码:
package code;
public class MyThread extends Thread {
public static void main(String[] args) {
MyThread th = new MyThread();
Thread t1 = new Thread(th, "Mythread");
t1.start();
System.out.println(Thread.currentThread().getName());
}
public void run()
{
Mythread1 th2 = new Mythread1();
Thread t2 = new Thread(th2, "Mythread1");
t2.start();
System.out.println(this.currentThread().getName());
}
class Mythread1 extends Thread
{
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(this.currentThread().getName());
}
}
}
代码如上,先用 MyThread 继承了 Thread 类,然后在 MyThread 类内部又写了一个 MyThread1 类,同样也是继承了 Thread 类,并且在 run 方法里面让它睡 1 秒,这样运行代码,就会打印出:
从上面的输出顺序可以看出,先是启动了 main 线程,然后再启动了 MyThread 线程,在 MyThread 线程中,又启动了 MyThread1 线程.但是由于让 MyThread1 线程睡了 1 秒,模拟处理后续业务,这样他就比 MyThread 运行完毕的时间晚一些.
现在,在代码中加上 CountDownLatch ,要让 MyThread1 先运行完毕,再让 MyThread 继续运行.
package code;
import java.util.concurrent.CountDownLatch;
public class MyThread extends Thread {
CountDownLatch countDownLatch = new CountDownLatch(1);
public static void main(String[] args) {
MyThread th = new MyThread();
Thread t1 = new Thread(th, "Mythread");
t1.start();
System.out.println(Thread.currentThread().getName());
}
public void run()
{
Mythread1 th2 = new Mythread1();
Thread t2 = new Thread(th2, "Mythread1");
t2.start();
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(this.currentThread().getName());
}
class Mythread1 extends Thread
{
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(this.currentThread().getName());
countDownLatch.countDown();
}
}
}
代码写法如上所示,大致分三步
1,我们先 new 一个 CountDownLatch 对象入参设置为 1(我个人理解的这个就像是 new 一个数组一样,什么时候数组清空了,那就可以让被中断的线程继续运行了)
2,在 MyThread 类中调用 countDownLatch.await(); 让当前线程停止运行.
3,在 Mythread1 类中调用 countDownLatch.countDown() 方法.当 Mythread1 全部执行完毕,再最后调用该方法,作用就是把我说的" 数组 " 清空.
看看输出的打印结果
结果如上图,是符合预期的结果的.
最后再说下 CountDownLatch countDownLatch = new CountDownLatch(1) 的入参,这块设置的是 1,那就需要调用一次 countDownLatch.countDown() 减去 1.
如果是其他数字,那就要调用相应的次数,否则调用 countDownLatch.await() 的线程都不会被继续执行.
来源: https://www.cnblogs.com/JJJ1990/p/8328319.html