8. Lock体系:是 JAVA语言自己实现的
sync是调用JVM的monitor指令
AQS (同步器)
ReentrantLock() //可重入锁
ReentReadWriteLock() //可重入读写锁
lockSupport //是用来创建锁和其他同步类的基本线程阻塞原语。
内建锁的wait方法只有一个
Condition(相当于内建锁的wait方法,但是一个lock有多个Condition)
8.1Lock简介
JDK1.5之后增加java.util.concurrent.locks提供了与内建锁完全不同的实现多线程共享资源访问机制。失去了内建锁隐式的加锁与解锁过程,增加了可中断的获取锁以及超时获取锁以及共享锁(读写锁)等内建锁比具备的特性
Lock lock=new ReentrantLock();
Try{
Lock.lock();//显式的上锁
//提下代码只有一个线程可以运行
。。。。同步块
Finally{
Lock.unlock();//显式的解锁}
8.2 lock的常用API
1.Void lock();//获取锁
2.void lockInterruptibly()throws InterruptedException();//获取锁的过程中能够响应中断(lock锁独有)
3.Boolean tryLock();//获取锁返回true,反之返回false,可以响应中断
4.Boolean tryLock(long time,TimeUnit unit);//在3的基础上增加了超时等待机制,在规定时间内未获取到锁,线程直接返回返回false(lock独有)
5.Condition newCondition();//获取与lock绑定的等待通知组件
6.Void unlock();//释放锁
8.3 AbstractQueuedSynchronizer (同步器),lock体系最核心的存在
RentrantLock中所有的方法实际上都是调用了其静态内部类Sync中的方法,而Sync继承了AQS
同步器是用来构建锁和其他同步组件的基础框架,它的实现主要依赖一个int成员变量来表示同步状态以及通过一个 FIFO队列构成等待队列。
要使用AQS,推荐使用静态内部类继承AQS,覆写AQS中的protected用来改变同步状态的方法,其他方法主要是 实现了排队和阻塞机制。状态的更新使用getState,setState以及compareAndSetState这三个方法
AQS的方法:
protected boolean tryAcquire(int arg)--独占式的获取锁
protected boolean tryRelease(int arg)--释放锁
protected int tryAcquireShared(int arg)--同步共享锁
protected boolean tryReleaseShared(int arg) --共享锁的释放
protected boolean isHeldExclusively()--当前是否持有锁
自己实现一个锁:代码如下:
package www.wl.java.link;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
class newBiLock implements Lock{
private Sync sync=new Sync ();
//自定义的静态内部类
static class Sync extends AbstractQueuedSynchronizer{
@Override
//规定同步状态为1
protected boolean tryAcquire(int arg) {
if(arg!=1){
throw new RuntimeException ("arg不为1");
}
if(compareAndSetState (0,1)){
setExclusiveOwnerThread (Thread.currentThread ());
return true;
}
return false;
}
@Override
protected boolean tryRelease(int arg) {
if(getState ()==0){
throw new IllegalMonitorStateException ();
}
setExclusiveOwnerThread (null);
setState (0);
return true;
}
@Override
//当前有没有拿到锁
protected boolean isHeldExclusively() {
return getState ()==1;
}
}
//lock接口方法————————————————————————————————————————————————————————————
@Override
public void lock() {
sync.acquire (1);
}
@Override
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly (1);
}
@Override
public boolean tryLock() {
return sync.tryAcquire (1);
}
@Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return sync.tryAcquireNanos (1,time);
}
@Override
public void unlock() {
sync.release (1);
}
@Override
//等待机制
public Condition newCondition() {
return null;
}
}
class MyThread implements Runnable{
Lock lock=new newBiLock ();
@Override
public void run() {
try{
lock.lock ();
try {
Thread.sleep (10000);
} catch (InterruptedException e) {
e.printStackTrace ();
}
}finally {
lock.unlock ();
}
}
}
public class WL {
public static void main(String[] args) {
MyThread myThread=new MyThread ();
for(int i=0;i<10;i++){
Thread thread=new Thread (myThread);
thread.start ();
}
}
}
结果:
- "Attach Listener"@541: RUNNING
- "DestroyJavaVM"@529 in group "main": RUNNING
- "Finalizer"@543: WAIT
- "Reference Handler"@544: WAIT
- "Signal Dispatcher"@542: RUNNING
- "Thread-0"@530 in group "main": SLEEPING
- "Thread-1"@531 in group "main": WAIT
- "Thread-2"@533 in group "main": WAIT
- "Thread-3"@534 in group "main": WAIT
- "Thread-4"@535 in group "main": WAIT
- "Thread-5"@536 in group "main": WAIT
- "Thread-6"@537 in group "main": WAIT
- "Thread-7"@538 in group "main": WAIT
- "Thread-8"@539 in group "main": WAIT
- "Thread-9"@540 in group "main": WAIT
结论:
Lock--面向使用者,定义了使用者与锁交互的接口,隐藏了实现细节
AQS面向锁的实现者,简化了锁的实现方式,屏蔽了同步状态的管理,线程排队,线程等待与唤醒等底层操作