Java高级技术第五章——高并发之CountDownLatch等同步器

前言

前言点击此处查看:
http://blog.csdn.net/wang7807564/article/details/79113195

Wait&Notify

引出一个问题:

实现一个容器,提供两个方法,add,size.
写两个线程,线程A添加10个元素到容器中,线程B实现监控元素的个数,当容器元素个数到5个时,线程B给出提示并结束。

这实际上是让我们手动实现一个观察者模式。
比较笨拙的实现方法是:使用volatile来修饰这个容器,然后在线程B中做一个while(true)的死循环来判断容器中的size.
但是,这种做法太过于浪费CPU资源。

一种比较好的解决方法是使用wait&notify组合方法来实现。这两个方法的实例化对象与synchronized作为锁定对象的原理类似:可以实例化一个临时对象,来调用这个对象的这两个方法来实现同步,例如:

Object o = new object();
在N个线程中,分别实现:
Synchronized(o){代码块};

这里面调用对象o的方法,来实现这样的同步。wait会释放锁,而notify不会释放锁。
但是,用这种方法来实现上述问题,需要监听线程B先执行,执行过程中,需要两个线程的notify和wait搭配使用。notify之后,A必须释放锁,B退出后,也必须notify,通知A继续执行。这样就可以做到两个线程A和B交替执行。
这个线程通信过程比较繁琐,在线程比较多的时候,一般都用notifyAll,很少有使用notify的。使用wait&notifyAll,常用来实现观察者模式,实现的方法同上。
需要说明的是,在使用wait之前进行条件判断的时候,不用if而用while,这是相当于多判断一次,可以防止再次被抢占。
相关代码网上有很多,没有什么太多的内容,而且这种方法现在已经不怎么使用了,在此不列举了。

CountDownLatch/CyclicBarrier/Semaphore

使用Latch(门闩)替代wait&notify来进行通知,好处是通信方式简单,同时也可以指定等待的时间。使用await和countdown方法替代wait和notify。 CountDownLatch不涉及锁定,当count的值为零时当前线程继续运行。
当不涉及同步,只是涉及线程通信的时候,用synchronized + wait/notify就显得太重了,
这时应该考虑countdownlatch/cyclicbarrier/semaphore这种同步器。
具体实现过程:

CountDownLatch latch = new CountDownLatch(1);

这里面实例化了一个CountDownLatch类,参数1代表每次只能被一个线程访问,这个过程与P-V源语类似。
A业务线程:判断条件不成立,latch.await();
B监听线程:判断条件成立,latch.countDown();

猜你喜欢

转载自blog.csdn.net/wang7807564/article/details/80048308