源码分析:
1、lock()加锁
调用AbstractQueuedSynchronizer类的acquire(int arg)方法如下:
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
方法tryAcquire(arg)使用子类继承重写。
方法addWaiter(Node.EXCLUSIVE), arg)创建双向链表,把新来的线程放入双向链表的等待队列中去。
方法acquireQueued将当前节点设置为等待状态
方法selfInterrupt方法中断当前线程
2、unlock()解锁
调用AbstractQueuedSynchronizer类的release(int arg)方法如下:
public final boolean release(int arg) {
if (tryRelease(arg)) {
Node h = head;
//头结点不为空且waitStatus 不等于0
if (h != null && h.waitStatus != 0)
//唤醒其它等待的线程
unparkSuccessor(h);
return true;
}
return false;
}
方法tryRelease(arg)使用子类继承重写。
继承AQS实现自己的锁的代码实现:
package cn.shiyujun.thread.thread4;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
/**
* AQS实现锁
*/
public class MyLock2 implements Lock{
private Hepler hepler = new Hepler();
private class Hepler extends AbstractQueuedSynchronizer{
@Override
protected boolean tryAcquire(int arg) {
// 如果第一个线程进来,可以拿到锁,因此我们可以返回true
// 如果第二个线程进来,则拿不到锁,返回false。有种特例,如果当前进来的线程和当前保存的线程是同一个线程,则可以拿到锁,但是有代价,要更新状态值
// 如何判断是第一个线程进来还是其他线程进来?
int state = getState();
Thread t = Thread.currentThread();
if(state == 0){
if(compareAndSetState(0,arg)){
//设置当前线程
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
}else if(getExclusiveOwnerThread() == t){ //判断进来的是不是当前线程,如果是当前线程状态加一,保证锁的重入
setState(state + 1);
return true;
}
return false;
}
@Override
protected boolean tryRelease(int arg) {
// 锁的获取与释放肯定是一一对应的,那么调用此方法的线程一定是当前线程
if(Thread.currentThread() != getExclusiveOwnerThread()){ //不是当前线程抛出异常
throw new RuntimeException();
}
int state = getState() - arg;
boolean flag = false;
if(state == 0){
setExclusiveOwnerThread(null);
flag = true;
}
setState(state);
return flag;
}
Condition newCondition(){
return new ConditionObject();
}
}
@Override
public void lock() {
hepler.acquire(1);
}
@Override
public void lockInterruptibly() throws InterruptedException {
hepler.acquireInterruptibly(1);
}
@Override
public boolean tryLock() {
return hepler.tryAcquire(1);
}
@Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return hepler.tryAcquireNanos(1,unit.toNanos(time));
}
@Override
public void unlock() {
hepler.release(1);
}
@Override
public Condition newCondition() {
return hepler.newCondition();
}
}
测试代码:
package cn.shiyujun.thread.thread4;
public class Main {
private int value;
private MyLock2 lock = new MyLock2();
public int next(){
lock.lock();
try {
Thread.sleep(300);
return value++;
} catch (InterruptedException e) {
throw new RuntimeException();
}finally {
lock.unlock();
}
}
public void a(){
lock.lock();
System.out.println("a");
b();
lock.unlock();
}
public void b(){
lock.lock();
System.out.println("b");
lock.unlock();
}
public static void main(String[] args) {
Main m = new Main();
//测试锁的重入
new Thread(new Runnable() {
@Override
public void run() {
m.a();
}
}).start();
//测试AQS锁
new Thread(new Runnable() {
@Override
public void run() {
while (true){
System.out.println(Thread.currentThread().getId() + " " + m.next());
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (true){
System.out.println(Thread.currentThread().getId() + " " + m.next());
}
}
}).start();
}
}