1.前提规定
我们规定state的值的表示意义:
0:表示没有被线程持有
1:表示被线程持有
此外,自定义的是不可重入锁,不需要记录获取锁的次数,另外我们自定义的锁支持条件变量
- state值的定义
- 不可重入锁
- 支持条件变量
2.自定义实现
自定义的锁的实现
import java.io.Serializable;import java.util.concurrent.TimeUnit;import java.util.concurrent.locks.AbstractQueuedSynchronizer;import java.util.concurrent.locks.Condition;public class NonReentrantLock implements Serializable {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 isLock(){return sync.isHeldExclusively();}public void lockInterrupti() throws InterruptedException {sync.acquireInterruptibly(1);}public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {return sync.tryAcquireNanos(1, unit.toNanos(timeout));}private static class Sync extends AbstractQueuedSynchronizer{/*** 判断锁是否被持有*/@Overrideprotected boolean isHeldExclusively() {return getState() == 1;}@Overrideprotected boolean tryAcquire(int acquires) {assert acquires == 1;if (compareAndSetState(0 ,1)){setExclusiveOwnerThread(Thread.currentThread());return true;}return false;}@Overrideprotected boolean tryRelease(int releases) {assert releases == 1;if (getState() == 0)throw new IllegalMonitorStateException();setExclusiveOwnerThread(null);setState(0);return true;}Condition newCondition(){return new ConditionObject();}}}
3.使用自定义的锁完成生产-消费模型
import java.util.Queue;import java.util.concurrent.LinkedBlockingDeque;import java.util.concurrent.locks.Condition;public class MyLockTest {final static NonReentrantLock LOCK = new NonReentrantLock();final static Condition NOT_FULL = LOCK.newCondition();final static Condition NOT_EMPTY = LOCK.newCondition();final static Queue<String> STRING_QUEUE = new LinkedBlockingDeque<>();final static int QUEUE_SIZE = 10;public static void main(String[] args) {Thread producer = new Thread(() -> {LOCK.lock();try {while (STRING_QUEUE.size() == QUEUE_SIZE){NOT_EMPTY.await();}STRING_QUEUE.add("ele");//唤醒消费则线程NOT_FULL.signalAll();;}catch (Exception e){e.printStackTrace();} finally {LOCK.unlock();}});Thread Consumer = new Thread(() -> {LOCK.lock();try {while (STRING_QUEUE.size() == 0){System.out.println("队列无数据,休息中");NOT_FULL.await();}String value = STRING_QUEUE.poll();System.out.println("获取的值:" + value);//唤醒生产者线程NOT_EMPTY.signalAll();;}catch (Exception e){e.printStackTrace();} finally {LOCK.unlock();}});//先启动消费者,大概率会去等待被唤醒Consumer.start();producer.start();}}
可以看到队列中的数据被成功的取出了
