您的位置:首页 > 编程语言 > Java开发

Java并发编程类学习五(同步工具)

2015-12-25 17:22 453 查看

内置锁(synchronized)

每个Java对象都对应有一个内置锁。有两种方式:第一种直接修饰方法;第二种synchronized后跟加锁的对象。

示范:

public synchronized void doSomething(Object obj){
synchronized(obj){
//execute action
}
}


CountDownLatch

CountDownLatch翻译为闭锁,是一种同步工具。CountDownLatch强调的是一个线程(或多个)需要等待另外的n个线程干完某件事情之后才能继续执行。

CountDownLatch使用countDown事件去控制并发。一般在用CountDownLatch的时候,对于同一个CountDownLatch对象,有两类线程:一类是在await,等待某个countDown事件发生,然后再执行后续操作;另一类完成了前期的准备工作,发起countDown事件。

参考我之前写的文章http://blog.csdn.net/csujiangyu/article/details/44236205

CyclicBarrier

CyclicBarrier翻译为栅栏,也是一种同步工具。它允许多个线程(或者说一组线程)在一个屏障点相互等待,直到每个线程到到达屏障点。CyclicBarrier本身是用线程的await()方法控制并发,每个线程都会参与其中,等到最后到达屏障点的线程后才执行后续操作。

参考我之前写的文章http://blog.csdn.net/csujiangyu/article/details/44338307

信号量

用来控制访问或者操作某个特定资源的线程数量。常用来实现某种资源池,或者对容器施加边界。

如果要实现一个有界缓存,最多只能有指定个数的线程访问缓存,可以这么实现:

public class BoundedCache<K, V> {
private static final int DEFAULT_SIZE = 10;

private Map<K, V> cache;
private final Semaphore sem;

public BoundedCache(int capacity){
this.sem = new Semaphore(capacity);
this.cache = new ConcurrentHashMap<>() ;
}

public BoundedCache(){
this(DEFAULT_SIZE);
}

public void put(K key, V value) throws InterruptedException{
sem.acquire();

try{
cache.put(key, value);
}finally{
sem.release();
}
}

public V get(K key) throws InterruptedException{
sem.acquire();
try{
return cache.get(key);
}finally{
sem.release();
}

}
}


ReentrantLock

一种显示锁,不同于内置锁,需要显示声明和使用。具体可参照我之前写的问题http://blog.csdn.net/csujiangyu/article/details/44002609

Condition

显示的Condition对象是一种更灵活的选择,提供了更丰富的功能:在每个锁上可以存在多个条件等待,条件等待可以是中断的或不可中断的,基于时限的等待,以及公平的或非公平的队列操作。可调用Lock.newCondition生成Condition对象。一个Lock可以有多个关联的Condition。

实现有界缓存:

public class ConditionBoundBuffer<V> {
private final V[] buf;
private int tail;
private int head;
private int count;
private Lock lock = new ReentrantLock();
private Condition notFull = lock.newCondition();
private Condition notEmpty = lock.newCondition();

@SuppressWarnings("unchecked")
public ConditionBoundBuffer(int capacity) {
buf = (V[]) new Object[capacity];
}
private void doPut(V v) {
buf[tail] = v;
if (++tail == buf.length)
tail = 0;
count++;
}
private V doTake() {
V v = buf[head];
if (++head == buf.length)
head = 0;
count--;
return v;
}
public void put(V v) throws InterruptedException {
lock.tryLock();
try {
while (count == buf.length) {
notFull.await();// 等待直到notfull
}
doPut(v);
notEmpty.signal();
} finally {
lock.unlock();
}
}
public V get() throws InterruptedException {
lock.tryLock();
try {
while (count == 0) {
notEmpty.await();// 等待直到notEmpty
}
V v = doTake();
notFull.signal();
return v;
} finally {
lock.unlock();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 并发编程