昨晚闲来翻了一会Java ConcurrentCy in Practise,
进一步明确了java 一些 Synchronizers的用法,在此简单记录一下
昨日随手写的demo代码。只是为了加深印象,所以不怎么讲究,如有看官路过请不要挑剔:
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class NightDinner {
private Semaphore sem=new Semaphore(3);
private CountDownLatch startLatch=new CountDownLatch(1);
private CountDownLatch latch=new CountDownLatch(4);
private CyclicBarrier barrier=new CyclicBarrier(2,new Runnable(){
public void run() {
System.out.println("barrier tripped");
}});
private ReentrantLock lock=new ReentrantLock();
private Condition condition=lock.newCondition();
public static void main(String[] args) {
NightDinner nd=new NightDinner();
nd.testLatch();
nd.testBarrier();
nd.testLock();
nd.testSemaphore();
}
public void testLatch(){
for(int i=0;i<4;i++){
new Thread(new AThread()).start();
}
startLatch.countDown();
System.out.println("latch begin");
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("latch zero reached");
}
public void testBarrier(){
for(int i=0;i<2;i++){
new Thread(new BThread()).start();
}
}
public void testLock(){
for(int i=0;i<3;i++)
new Thread(new CThread()).start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.lock();
//condition.signal();
condition.signalAll();
//要显式地释放掉lock的锁
lock.unlock();
}
public void testSemaphore(){
for(int i=0;i<4;i++)
new Thread(new DThread()).start();
}
public class AThread implements Runnable{
public void run() {
try {
startLatch.await();
} catch (InterruptedException e) {
}
latch.countDown();
System.out.println("latch down1");
}
}
public class BThread implements Runnable{
public void run() {
try {
System.out.println("barrier begints to await");
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
public class CThread implements Runnable{
public void run() {
lock.lock();
try {
System.out.println("lock got.conditon begins to wait");
//condition的wait方法将release当前线程持有的condtion相关的lock的锁,然后等待被唤醒
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
finally{
System.out.println("conditon signaled");
lock.unlock();
}
}
}
public class DThread implements Runnable{
public void run() {
boolean suc=sem.tryAcquire();
System.out.println("sem result:"+suc);
}
}
}
总结一下,就是:
CountdownLatch:
一个主人线程一直await,知道所有客人线程都countdown并且latch的值为0,那么
主人认为时机已成熟,开饭。
CyclicBarrier:
一桌有10个位子,人不满不能开席(定义cyclicbarrier的时候可选的runnable行为)。于是,来了一个(await),又来了一个...第10个来了,barrier发现时机已成熟,开饭。
Semapore:
一桌有10个位子。来了一个(acquire)..第10个来了....第11个来了....哈哈,没有位子了,站着吧
ReentrantLock:
这个官方文档可能读起来不是很顺畅,还是通过代码明白得更深入一些。
一个lock可以有多个Condtion。每个Condtion都有一个管理的lock。
Conditon可以await(释放掉关联的Lock的锁,等待notif),也可以notify(通知其他线程处于condtion await 状态的线程可以做好继续获取lock的锁的准备了。notify之后要显式地释放掉lock锁).