锁代码
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
public class MyLock2 implements Lock{
//AQS实现重入锁
private Helper helper = new Helper();
private class Helper extends AbstractQueuedSynchronizer{
@Override
protected boolean tryAcquire(int arg) {
// 第一个线程进来,可以拿到锁,返回true
int state = getState();
Thread t = Thread.currentThread();
// 第一次进入,state为0
if (state == 0) {
// 保证原子性,状态改后,保证后续线程访问时,状态值为1
if(compareAndSetState(0, arg)){
setExclusiveOwnerThread(t);
return true;
}
// 第二个线程进入,无法拿锁,返回false 若进来的线程是同一个线程,
//则允许,但是需要更新状态值
// 判断若进来的线程是同一个线程,则允许,但是需要更新状态值
}else if(getExclusiveOwnerThread() == t){
setState(state+1);
return true;
}
// 如何判断第一个线程还是第二个还是其他
// 依靠单个原子int值表示状态
return false;
}
@Override
protected boolean tryRelease(int arg) {
// TODO Auto-generated method stub
// 锁的获取和释放肯定是一一对应,那么调用此方法的线程一定是当前线程
if (Thread.currentThread()!= getExclusiveOwnerThread()) {
throw new RuntimeException();
}
// arg=1 当前(state-1 )为0表示,线程可以解锁
int state = getState() -arg;
boolean flag = false;
// 判断重入的锁都释放
if (state == 0) {
setExclusiveOwnerThread(null);
flag = true;
}
// 每次锁进入一次,就更新一次状态state
setState(state);
return flag;
}
}
@Override
public void lock() {
// TODO Auto-generated method stub
helper.acquire(1);
}
@Override
public void lockInterruptibly() throws InterruptedException {
// TODO Auto-generated method stub
}
@Override
public boolean tryLock() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean tryLock(long time, TimeUnit unit)
throws InterruptedException {
// TODO Auto-generated method stub
return false;
}
@Override
public void unlock() {
// TODO Auto-generated method stub
helper.release(1);
}
@Override
public Condition newCondition() {
// TODO Auto-generated method stub
return null;
}
}
示例
import java.util.concurrent.locks.Lock;
public class Main {
private int v;
Lock lock = new MyLock2();
public int getnext() {
lock.lock();
int a = v++;
lock.unlock();
return a;
}
public static void main(String[] args) {
Main m = new Main();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
while (true) {
System.out.println(Thread.currentThread().getName()+" "+m.getnext());
}
}
}).start();
}
}