Java中的锁
1.简介
2.java.util.concurrent包
Lock接口
//试图获取锁.
void lock()
//如果当前线程未被中断,则获取锁.
void lockInterruptibly()
//返回绑定到此 Lock 实例的新 Condition 实例.
Condition newCondition()
//仅在调用时锁为空闲状态才获取该锁.
boolean tryLock()
//如果锁在给定的等待时间内空闲,并且当前线程未被中断,则获取锁.
boolean tryLock(long time, TimeUnit unit)
//试图释放锁.
void unlock()
ReentranLock类
//创建一个 ReentrantLock 的实例.
ReentrantLock()
//创建一个具有给定公平策略的 ReentrantLock实例.
ReentrantLock(boolean fair)
//试图获取锁.
void lock()
//如果当前线程未被中断,则获取锁.
void lockInterruptibly()
//仅在调用时锁未被另一个线程保持的情况下,才获取该锁.
boolean tryLock()
//如果锁在给定等待时间内没有被另一个线程保持,且当前线程未被中断,则获取该锁.
boolean tryLock(long timeout, TimeUnit unit)
//试图释放此锁.
void unlock()
//返回用来与此 Lock 实例一起使用的 Condition 实例.
Condition newCondition()
//如果此锁的公平设置为 true,则返回 true.
boolean isFair()
//返回正等待获取此锁的线程估计数.
int getQueueLength()
//返回等待与此锁相关的给定条件的线程估计数.
int getWaitQueueLength(Condition condition)
//返回标识此锁及其锁定状态的字符串.
String toString()
Condition接口
//使当前线程在接收到信号前或被中断前一直保持等待状态.
void await()
//使当前线程在接收到信号前或被中断前或达到指定时间前一直保持等待状态(TimeUnit为时间单位).
boolean await(long time, TimeUnit unit)
//使当前线程在接收到信号前或被中断前或达到指定时间前一直保持等待状态(单位为毫秒).
long awaitNanos(long nanosTimeout)
//使当前线程在接收到信号前或被中断前或达到最后日期期限前一直保持等待状态.
boolean awaitUntil(Date deadline)
//唤醒一个在该Condition实例等待的线程.
void signal()
//唤醒所有在该Condition实例等待的线程.
void signalAll()
/** * @Auther: ZHUANGHAOTANG * @Date: 2018/9/26 17:36 * @Description: */ public class TestReentranLock implements Runnable{ /** * 可重入锁 */ private ReentrantLock reentrantLock = new ReentrantLock(true); /** * 锁条件 */ private Condition condition = reentrantLock.newCondition(); /** * 业务处理 */ public void service(){ String threadName = Thread.currentThread().getName(); System.out.println(threadName+":尝试获取锁"); reentrantLock.lock(); System.out.println(threadName+":获取锁成功"); try { System.out.println(threadName+":使当前线程等待,并释放锁资源。"); condition.await(); } catch (InterruptedException e) { e.printStackTrace(); }finally { reentrantLock.unlock(); System.out.println(threadName+":释放锁"); } } /** * 唤醒在该Condition实例等待的线程 */ public void signalAll(){ reentrantLock.lock(); condition.signalAll(); reentrantLock.unlock(); } @Override public void run() { service(); } public static void main(String[] args) { TestReentranLock testReentranLock = new TestReentranLock(); Thread threadA = new Thread(testReentranLock,"线程A"); Thread threadB = new Thread(testReentranLock,"线程B"); Thread threadC = new Thread(testReentranLock,"线程C"); threadA.start(); threadB.start(); threadC.start(); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } testReentranLock.signalAll(); } }
线程B:尝试获取锁
线程A:尝试获取锁
线程B:获取锁成功
线程C:尝试获取锁
线程B:使当前线程等待,并释放锁资源。
线程A:获取锁成功
线程A:使当前线程等待,并释放锁资源。
线程C:获取锁成功
线程C:使当前线程等待,并释放锁资源。
线程B:释放锁
线程C:释放锁
线程A:释放锁
线程B:尝试获取锁
线程A:尝试获取锁
线程A:获取锁成功
线程C:尝试获取锁
线程A:使当前线程等待,并释放锁资源。
线程C:获取锁成功
线程C:使当前线程等待,并释放锁资源。
线程B:获取锁成功
线程B:使当前线程等待,并释放锁资源。
线程A:释放锁
线程B:释放锁
线程C:释放锁
ReadWriteLock接口
//返回用于读取操作的锁.
Lock readLock()
//返回用于写入操作的锁.
Lock writeLock()
ReentrantReadWriteLock类
//创建一个ReentrantReadWriteLock实例.
ReentrantReadWriteLock()
//创建一个具有给定公平策略的ReentrantReadWriteLock实例.
ReentrantReadWriteLock(boolean fair)
//返回用于读取操作的锁.
Lock ReentrantReadWriteLock。ReadLock。readLock()
//返回用于写入操作的锁.
Lock ReentrantReadWriteLock。WriteLock。writeLock()
//返回等待获取读取或写入锁的线程估计数目.
int getQueueLength()
//如果此锁的公平设置为 true,则返回 true.
boolean isFair()
//返回标识此锁及其锁状态的字符串.
String toString()
ReadLock/WriteLock静态内部类
//试图获取锁.
void lock()
//如果当前线程未被中断,则获取锁.
void lockInterruptibly()
//返回绑定到此 Lock 实例的新 Condition 实例.
Condition newCondition()
//仅在调用时锁为空闲状态才获取该锁.
boolean tryLock()
//如果锁在给定的等待时间内空闲,并且当前线程未被中断,则获取锁.
boolean tryLock(long time, TimeUnit unit)
//试图释放锁.
void unlock()
//返回标识此锁及其锁状态的字符串.
String toString()
/** * @Auther: ZHUANGHAOTANG * @Date: 2018/9/26 18:04 * @Description: */ public class TestReentrantReadWriteLock implements Runnable{ private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock(true); /** * 读锁 */ private Lock readLock = reentrantReadWriteLock.readLock(); /** * 写锁 */ private Lock writeLock = reentrantReadWriteLock.writeLock(); /** * 读取操作 */ public void reading(){ String threadName = Thread.currentThread().getName(); System.out.println(threadName+":尝试获取读锁"); readLock.lock(); System.out.println(threadName+":获取读锁成功"); System.out.println(threadName+":释放读锁"); readLock.unlock(); } /** * 写入操作 */ public void writing(){ String threadName = Thread.currentThread().getName(); System.out.println(threadName+":尝试获取写锁"); writeLock.lock(); System.out.println(threadName+":获取写锁成功"); System.out.println(threadName+":释放写锁"); writeLock.unlock(); } public static void main(String[] args) { TestReentrantReadWriteLock testReentrantReadWriteLock = new TestReentrantReadWriteLock(); Thread threadA = new Thread(testReentrantReadWriteLock,"线程A"); Thread threadB = new Thread(testReentrantReadWriteLock,"线程B"); Thread threadC = new Thread(testReentrantReadWriteLock,"线程C"); threadA.start(); threadB.start(); threadC.start(); } }
@Override
public void run() {
//读读共享
reading();
}
线程A:尝试获取读锁
线程B:尝试获取读锁
线程A:获取读锁成功
线程A:释放读锁
线程C:尝试获取读锁
线程C:获取读锁成功
线程C:释放读锁
线程B:获取读锁成功
线程B:释放读锁
@Override
public void run() {
//写写互斥
writing();
}
线程A:尝试获取写锁
线程B:尝试获取写锁
线程A:获取写锁成功
线程C:尝试获取写锁
线程A:释放写锁
线程B:获取写锁成功
线程B:释放写锁
线程C:获取写锁成功
线程C:释放写锁
@Override
public void run() {
//读写互斥
writing();
reading();
}
线程A:尝试获取写锁
线程C:尝试获取写锁
线程B:尝试获取写锁
线程A:获取写锁成功
线程A:释放写锁
线程A:尝试获取读锁
线程C:获取写锁成功
线程C:释放写锁
线程C:尝试获取读锁
线程B:获取写锁成功
线程B:释放写锁
线程B:尝试获取读锁
线程C:获取读锁成功
线程C:释放读锁
线程A:获取读锁成功
线程A:释放读锁
线程B:获取读锁成功
线程B:释放读锁