手写Lockl锁
可分为三步:
1.实现Lock类;
2.实现lock()
3.实现unlock()
以下图形象的表示抢锁与释放锁过程
相关代码如下:
package myLock; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.LockSupport; /** * 简单描述 * * @author lijie * @data 2021/5/11 22:17 */ public class JieLock implements Lock { // 房卡,用来登记线程 AtomicReference<Thread> owners = new AtomicReference<>(); // 队列(此队列安全+高效)。用来存放没有抢到锁的线程 LinkedBlockingQueue<Thread> waiters = new LinkedBlockingQueue<>(); @Override public void lock() { while (!owners.compareAndSet(null, Thread.currentThread())) { // 若抢不到锁,则等待 waiters.add(Thread.currentThread()); // 让当前线程阻塞 LockSupport.park(); // 当不阻塞时,从队列中将该线程移除 waiters.remove(Thread.currentThread()); } } @Override public void lockInterruptibly() throws InterruptedException { } @Override public boolean tryLock() { return false; } @Override public boolean tryLock(long time, TimeUnit unit) throws InterruptedException { return false; } @Override public void unlock() { // 只有持有锁的线程才可以释放锁 if (owners.compareAndSet(Thread.currentThread(), null)) { for (Thread waiter : waiters) { LockSupport.unpark(waiter); } } else { } } @Override public Condition newCondition() { return null; } }
进行测试:
package myLock; /** * 简单描述 * * @author lijie * @data 2021/5/11 22:35 */ public class TestLock { int i = 10000; JieLock lock = new JieLock(); public void order(){ lock.lock(); try { i--; } finally { lock.unlock(); } } public static void main(String[] args) throws InterruptedException { TestLock lock1 = new TestLock(); for (int i = 0; i < 10; i++) { new Thread(()->{ for (int j = 0; j < 1000; j++) { lock1.order(); } }).start(); } // 等待线程执行完操作 Thread.sleep(2000); System.out.println(lock1.i); } }