基于 ReentrantLock实现一个锁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| package aqsLock;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
public class aqsLock { public void lock() { sync.acquire(1); }
public void unlock() { sync.release(1); }
private final Sync sync = new Sync();
public static class Sync extends AbstractQueuedSynchronizer { @Override protected boolean tryAcquire(int arg) { if (compareAndSetState(0, 1)) return true; return false; }
@Override protected boolean tryRelease(int arg) { setState(0); return true; } } }
|
基本功能实现,测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| private static long count = 0;
public static void main(String[] args) throws Exception { Thread th1 = new Thread(()-> add()); Thread th2 = new Thread(()-> add()); th1.start(); th2.start(); th1.join(); th2.join(); System.out.println(count); }
private static ExampleLock exampleLock = new ExampleLock();
private static void add() { exampleLock.lock(); for (int i = 0; i < 10000; i++) { count++; } add2(); exampleLock.unlock(); }
|
非公平锁,因为线程抢锁不排队,纯看脸。
实现的排队获取锁,叫公平锁,因为只要有线程在排队,新来的就得乖乖去排队,不能直接抢。
实现一个公平锁
1 2 3 4 5 6 7 8 9 10 11 12
| @Override public boolean tryAcquire(int acquires) { if (有线程在等待队列中) { return false; } if (compareAndSetState(0, 1)) { return true; } return false; }
|
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| package aqsLock;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
public class aqsLock { public aqsLock(boolean fair) { sync = fair ? new Sync() : new NofairSync(); }
public void lock() { sync.acquire(1); }
public void unlock() { sync.release(1); }
private Sync sync = new Sync();
public static class Sync extends AbstractQueuedSynchronizer { @Override protected boolean tryAcquire(int arg) { if (hasQueuedPredecessors() && compareAndSetState(0, 1)) return true; return false; }
@Override protected boolean tryRelease(int arg) { setState(0); return true; } }
public static class NofairSync extends Sync { @Override protected boolean tryAcquire(int arg) { if (compareAndSetState(0, 1)) return true; return false; }
@Override protected boolean tryRelease(int arg) { setState(0); return true; } } }
|
工具会导致一个线程卡死,一直获取不到锁
实现方法可以重入
1 2 3 4 5 6 7 8 9 10 11
| public void doSomeThing2() { flashLock.lock(); doSomeThing2(); flashLock.unlock(); }
public void doSomeThing2() { flashLock.lock(); ... flashLock.unlock(); }
|
一个线程执行了一个方法,获取了锁,这个方法没有结束,又调用了另一个需要锁的方法,于是卡在这再也不走了。
怎么 让同一个线程持有锁时,还能继续获取锁(可重入),只有当不同线程才互斥呢?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| @Override public boolean tryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { if (hasQueuedPredecessors() && compareAndSetState(0, 1)) { setExclusiveOwnerThread(current); return true; } } else if (current == getExclusiveOwnerThread()) { setState(c + acquires); return true; } return false; }
|