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

内置锁(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,并发编程)