(原创)JAVA多线程三锁
前两章介绍了锁,那么现在我们介绍新的一个类,锁
一,简介
Lock是一个接口,实现它的类有读锁,写锁,和ReentrantLock,我们可以在类上点击ctrl+t来看看有哪些类实现了这个接口
使用方法
private Lock l = new ReentrantLock(); try{ l.lock(); if(ticketCount > 0){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+ "卖出了第"+(ticketCount--)+"张票"); } } finally{ l.unlock(); }
特别注意,要在最后unlock锁,否则这个锁会一直锁着,导致别的无法使用
二,读锁和写锁
这里有一个例子,读写锁的缓存应用,如下所示
package cn.unis; import java.util.HashMap; import java.util.Map; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; public class CacheDemo { public Map<String, Object> cached = new HashMap<String, Object>(); private ReadWriteLock rwl = new ReentrantReadWriteLock(); public Object getobject(String keyname) { rwl.readLock().lock(); // 读数据前先加锁 Object value = null; try { value = cached.get(keyname); if (value == null) { //发现数据是空的,则写数据,先开启写锁 rwl.readLock().unlock(); rwl.writeLock().lock(); try { if (value == "" || value == null) { value = "test"; } } finally { rwl.writeLock().lock(); rwl.readLock().lock(); } } } finally { rwl.readLock().unlock(); } return value; } }
三,Condition实现线程同步通信
类似于传统线程技术中的object.wait()和object.notifyall()方法
可以这样说,他替代了wait方法,用的是如下的代码,注意,Condition是基于Lock的
Lock lock = new ReentrantLock(); Condition condition = lock.newCondition();
使用方法是:
condition.await();
condition.signal();
在SDK里面有一个例子,缓冲区的例子,可以参考一下
class BoundedBuffer { final Lock lock = new ReentrantLock(); final Condition notFull = lock.newCondition(); final Condition notEmpty = lock.newCondition(); final Object[] items = new Object[100]; int putptr, takeptr, count; public void put(Object x) throws InterruptedException { lock.lock(); try { while (count == items.length) notFull.await(); items[putptr] = x; if (++putptr == items.length) putptr = 0; ++count; notEmpty.signal(); } finally { lock.unlock(); } } public Object take() throws InterruptedException { lock.lock(); try { while (count == 0) notEmpty.await(); Object x = items[takeptr]; if (++takeptr == items.length) takeptr = 0; --count; notFull.signal(); return x; } finally { lock.unlock(); } } }