1.前提规定

我们规定state的值的表示意义:

0:表示没有被线程持有
1:表示被线程持有

此外,自定义的是不可重入锁,不需要记录获取锁的次数,另外我们自定义的锁支持条件变量

  • state值的定义
  • 不可重入锁
  • 支持条件变量

2.自定义实现

自定义的锁的实现

  1. import java.io.Serializable;
  2. import java.util.concurrent.TimeUnit;
  3. import java.util.concurrent.locks.AbstractQueuedSynchronizer;
  4. import java.util.concurrent.locks.Condition;
  5. public class NonReentrantLock implements Serializable {
  6. private final Sync sync = new Sync();
  7. public void lock(){
  8. sync.acquire(1);
  9. }
  10. public boolean tryLock(){
  11. return sync.tryAcquire(1);
  12. }
  13. public void unlock(){
  14. sync.release(1);
  15. }
  16. public Condition newCondition(){
  17. return sync.newCondition();
  18. }
  19. public boolean isLock(){
  20. return sync.isHeldExclusively();
  21. }
  22. public void lockInterrupti() throws InterruptedException {
  23. sync.acquireInterruptibly(1);
  24. }
  25. public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
  26. return sync.tryAcquireNanos(1, unit.toNanos(timeout));
  27. }
  28. private static class Sync extends AbstractQueuedSynchronizer{
  29. /**
  30. * 判断锁是否被持有
  31. */
  32. @Override
  33. protected boolean isHeldExclusively() {
  34. return getState() == 1;
  35. }
  36. @Override
  37. protected boolean tryAcquire(int acquires) {
  38. assert acquires == 1;
  39. if (compareAndSetState(0 ,1)){
  40. setExclusiveOwnerThread(Thread.currentThread());
  41. return true;
  42. }
  43. return false;
  44. }
  45. @Override
  46. protected boolean tryRelease(int releases) {
  47. assert releases == 1;
  48. if (getState() == 0)
  49. throw new IllegalMonitorStateException();
  50. setExclusiveOwnerThread(null);
  51. setState(0);
  52. return true;
  53. }
  54. Condition newCondition(){
  55. return new ConditionObject();
  56. }
  57. }
  58. }

3.使用自定义的锁完成生产-消费模型

  1. import java.util.Queue;
  2. import java.util.concurrent.LinkedBlockingDeque;
  3. import java.util.concurrent.locks.Condition;
  4. public class MyLockTest {
  5. final static NonReentrantLock LOCK = new NonReentrantLock();
  6. final static Condition NOT_FULL = LOCK.newCondition();
  7. final static Condition NOT_EMPTY = LOCK.newCondition();
  8. final static Queue<String> STRING_QUEUE = new LinkedBlockingDeque<>();
  9. final static int QUEUE_SIZE = 10;
  10. public static void main(String[] args) {
  11. Thread producer = new Thread(() -> {
  12. LOCK.lock();
  13. try {
  14. while (STRING_QUEUE.size() == QUEUE_SIZE){
  15. NOT_EMPTY.await();
  16. }
  17. STRING_QUEUE.add("ele");
  18. //唤醒消费则线程
  19. NOT_FULL.signalAll();;
  20. }catch (Exception e){
  21. e.printStackTrace();
  22. } finally {
  23. LOCK.unlock();
  24. }
  25. });
  26. Thread Consumer = new Thread(() -> {
  27. LOCK.lock();
  28. try {
  29. while (STRING_QUEUE.size() == 0){
  30. System.out.println("队列无数据,休息中");
  31. NOT_FULL.await();
  32. }
  33. String value = STRING_QUEUE.poll();
  34. System.out.println("获取的值:" + value);
  35. //唤醒生产者线程
  36. NOT_EMPTY.signalAll();;
  37. }catch (Exception e){
  38. e.printStackTrace();
  39. } finally {
  40. LOCK.unlock();
  41. }
  42. });
  43. //先启动消费者,大概率会去等待被唤醒
  44. Consumer.start();
  45. producer.start();
  46. }
  47. }

可以看到队列中的数据被成功的取出了
image.png