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/44002609Condition
显示的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对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树