import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.LockSupport; public class MyLock implements Lock { // 锁的状态 0 - 未占用 1 - 占用 AtomicInteger state = new AtomicInteger(); // 当前占用的线程 Thread ownerThread = null; // 当前等待抢锁的线程 LinkedBlockingDeque<Thread> waiters = new LinkedBlockingDeque<>(); @Override public void lock() { if (!tryLock()) { waiters.add(Thread.currentThread()); // 1. 先排队 for (;;) { if (tryLock()) { // 如果某一个线程抢到了锁,自己把自己从队列里面挪出来 waiters.poll(); return; } else { LockSupport.park(); // 2. 等呗 -- 等待到何时再执行?唤醒目的是继续抢锁 } } } } @Override public void unlock() { if (ownerThread != Thread.currentThread()) { throw new RuntimeException("非法调用---当前这个锁不属于你"); } if (state.decrementAndGet() == 0) { //减1等0 - 0代表锁未被占用 ownerThread = null; // 通知其他正在等待的线程 Thread waiterThread = waiters.peek();// 取出队列的第一个(但队列中仍然存在)FIFO先进先出 LockSupport.unpark(waiterThread); } } @Override public boolean tryLock() { // 把 0 - 1 if (state.get() == 0) { // CAS 底层c++实现 保证N个线程同事操作,只有一个线程操作成功 if (state.compareAndSet(0, 1)) { ownerThread = Thread.currentThread(); return true; } } return false; } @Override public boolean tryLock(long time, TimeUnit unit) throws InterruptedException { return false; } @Override public Condition newCondition() { return null; } @Override public void lockInterruptibly() throws InterruptedException { } }
测试类
import java.util.Date; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class LockDemo { // static Lock lock = new ReentrantLock(); //默认非公平 static Lock lock = new MyLock(); // new ReentrantLock(true); 公平锁 public static void main(String[] args) throws InterruptedException { // 主线程获取到锁 lock.lock(); // 其他没有获取到锁 阻塞 卡住不动 System.out.println("主线程获取到锁 其他线程卡住不动 " + Thread.currentThread().getName() + new Date()); Thread thread = new Thread(new Runnable() { @Override public void run() { lock.lock(); System.out.println(Thread.currentThread().getName() + "---获取到锁---"); lock.unlock(); System.out.println(Thread.currentThread().getName() + "---释放锁---"); } }); thread.start(); // 主线程睡眠3s Thread.sleep(3000L); lock.unlock(); System.out.println("3s后主线程释放锁 其他线程可以开始抢锁 " + Thread.currentThread().getName() + new Date()); } }
主线程获取到锁 其他线程卡住不动 mainSat May 23 16:48:40 CST 2020
3s后主线程释放锁 其他线程可以开始抢锁 mainSat May 23 16:48:43 CST 2020
Thread-0---子线程获取到锁---
Thread-0---子线程释放锁---
原文:https://www.cnblogs.com/south-pigeon/p/12943319.html