今天主要基于上一节的文章,其实这两张连起来是阿里的一道面试题。上一节我们说明了notify不能释放锁,那么怎么能做到及时通知呢?这时就可以用concurrent包下的一个同步工具类:CountDownLatch。
代码说明:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
/**
* 注意:wait方法是释放锁的,notify方法不会释放锁
* @author lihao
*
*/
public class MyThread6 {
private volatile List list = new ArrayList<>();
private static CountDownLatch downLatch = new CountDownLatch(1);
public void add() {
list.add("主席");
}
public int getSize() {
return list.size();
}
public static void main(String[] args) {
MyThread6 myThread6 = new MyThread6();
//Object obj = new Object();
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
//synchronized (obj) {
for(int i=0;i<10;i++){
myThread6.add();
System.out.println("线程" + Thread.currentThread().getName() + "添加了一个元素");
try {
Thread.sleep(1000);
if (myThread6.getSize() == 5) {
System.out.println("发出通知");
//obj.notifyAll();
downLatch.countDown();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//}
}
},"t1");
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
//synchronized (obj) {
if(myThread6.getSize()!=5){
try {
//obj.wait();
downLatch.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("收到通知");
throw new RuntimeException();
//}
}
});
thread2.start();
thread.start();
}
}
输出结果:
线程t1添加了一个元素
线程t1添加了一个元素
线程t1添加了一个元素
线程t1添加了一个元素
线程t1添加了一个元素
发出通知
Exception in thread "Thread-0" 线程t1添加了一个元素
收到通知
java.lang.RuntimeException
at cn.lh.bf.MyThread6$2.run(MyThread6.java:64)
at java.lang.Thread.run(Thread.java:745)
线程t1添加了一个元素
线程t1添加了一个元素
线程t1添加了一个元素
线程t1添加了一个元素
你会发现代码还变简单了,那么CountDownLatch这个类到底是什么意思呢?
你会发现在构造函数中我们传递了一个int数值,其实这个类就像一个计数器,每次调用
downLatch.countDown();
方法会将我们构造时的int值减一操作,当该值为0时会立即唤醒所有使用downLatch.await();等待的线程。
综上:其实为阿里的一道面试题,谢谢大家