主要针对AQS原理进行巩固,利用自定义的同步器实现不可重入锁

自定义锁

部分方法直接使用父类的同步器实现的

  1. public class NonReentrantLock implements Lock {
  2. private final NonReentrantSync sync = new NonReentrantSync();
  3. // 尝试,不成功,进入等待队列
  4. @Override
  5. public void lock() {
  6. sync.acquire(1);
  7. }
  8. // 尝试,不成功,进入等待队列,可打断
  9. @Override
  10. public void lockInterruptibly() throws InterruptedException {
  11. sync.acquireSharedInterruptibly(1);
  12. }
  13. //尝试一次,不成功返回,不进入队列
  14. @Override
  15. public boolean tryLock() {
  16. return sync.tryAcquire(1);
  17. }
  18. /**
  19. * @throws
  20. * @description 尝试,不成功,进入等待队列,有时限
  21. * @author SongHongWei
  22. * @params
  23. * @updateTime 2021/10/5 12:21
  24. */
  25. @Override
  26. public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
  27. return sync.tryAcquireSharedNanos(1, unit.toNanos(time));
  28. }
  29. //释放锁
  30. @Override
  31. public void unlock() {
  32. sync.release(1);
  33. }
  34. //生成条件变量
  35. @Override
  36. public Condition newCondition() {
  37. return sync.newCondition();
  38. }
  39. }

自定义同步器

只是实现了独占锁的实现方法

  1. public class NonReentrantSync extends AbstractQueuedSynchronizer {
  2. protected Condition newCondition() {
  3. return new ConditionObject();
  4. }
  5. /**
  6. * @throws
  7. * @description 尝试获取资源,立即返回。成功则返回true,否则false。
  8. * @author SongHongWei
  9. * @params
  10. * @updateTime 2021/10/5 12:14
  11. */
  12. @Override
  13. protected boolean tryAcquire(int arg) {
  14. // 这里限定只能为1个量
  15. if (arg == 1) {
  16. //state为0才设置为1,不可重入
  17. if (compareAndSetState(0, 1)) {
  18. //设置为当前线程独占资源
  19. setExclusiveOwnerThread(Thread.currentThread());
  20. return true;
  21. }
  22. }
  23. return false;
  24. }
  25. /**
  26. * @throws
  27. * @description 尝试释放资源,立即返回。成功则为true,否则false。
  28. * @author SongHongWei
  29. * @params
  30. * @updateTime 2021/10/5 12:17
  31. */
  32. @Override
  33. protected boolean tryRelease(int arg) {
  34. //限定为1个量
  35. if(arg == 1) {
  36. ///既然来释放,那肯定就是已占有状态了。只是为了保险,多层判断
  37. if(getState() == 0) {
  38. throw new IllegalMonitorStateException();
  39. }
  40. setExclusiveOwnerThread(null);
  41. //释放资源,放弃占有状态
  42. setState(0);
  43. return true;
  44. }
  45. return false;
  46. }
  47. @Override
  48. protected boolean isHeldExclusively() {
  49. return getState() == 1;
  50. }

测试类

测试结果,t1线程始终获取不到第二次锁

  1. public class AqsClient {
  2. static final NonReentrantLock lock = new NonReentrantLock();
  3. public static void main(String[] args) {
  4. log.info("主线程启动....");
  5. new Thread(() -> {
  6. lock.lock();
  7. log.info("线程t1第一次获取锁...");
  8. try {
  9. log.info("线程t1尝试再次获取锁...");
  10. lock.lock();
  11. log.info("线程t1再次获取锁成功");
  12. lock.unlock();
  13. log.info("线程t1释放重入锁...");
  14. } finally {
  15. lock.unlock();
  16. log.info("线程t1释放锁");
  17. }
  18. }, "t1").start();
  19. }
  20. }