独占锁:有且只有一个线程能持有该锁,而且获得锁的线程也只能获得一次,不能获得多次
package day1;
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 MutexLock implements Lock {
// 静态内部类,自定义同步器
private static class Sync extends AbstractQueuedSynchronizer {
/**
*
*/
private static final long serialVersionUID = 1L;
// 是否处于占用状态
protected boolean isHeldExclusively() {
return getState() == 1;
}
// 当状态为0的时候获取锁
public boolean tryAcquire(int acquires) {
//独占锁实现的关键,只有锁没有被占时才可能获得锁
if (compareAndSetState(0, 1)) {
//获得锁成功,设置拥有锁的线程为当前线程
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
// 释放锁,将状态设置为0
protected boolean tryRelease(int releases) {
if (getState() == 0)
throw new IllegalMonitorStateException();
setExclusiveOwnerThread(null);
setState(0);
return true;
}
// 返回一个Condition,每个condition都包含了一个condition队列
Condition newCondition() {
return new ConditionObject();
}
}
// 仅需要将操作代理到Sync上即可
private final Sync sync = new Sync();
public void lock() {
sync.acquire(1);
}
public boolean tryLock() {
return sync.tryAcquire(1);
}
public void unlock() {
sync.release(1);
}
public Condition newCondition() {
return sync.newCondition();
}
public boolean isLocked() {
return sync.isHeldExclusively();
}
public boolean hasQueuedThreads() {
return sync.hasQueuedThreads();
}
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}
}
如果是一个回调方法的话,会形成死锁,如:
package day1;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MutexLockTest {
private static MutexLock lock = new MutexLock();
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.execute(new Thread1());
executor.shutdown();
}
static class Thread1 implements Runnable {
@Override
public void run() {
try {
lock.lock();
lock.lock();
System.out.println(sumNum(1,100));
} finally {
lock.unlock();
}
}
int sum = 0;
public int sumNum(int start,int end) {
if(start <=end) {
sum = sum+start;
sumNum(start+1,end);
}
return sum;
}
}
}