java可重入锁synchronized和ReentrantLock

柔光的暖阳◎ 2021-09-24 09:04 492阅读 0赞

什么就叫可重入锁?
可重入锁也叫可重复可递归调用的锁,同一线程外层函数获得锁之后,在进入内层方法的时候会自动获取锁,然后使用,无需等待去再次获取锁,并且不发生死锁(前提得是同一个对象或者class),这样的锁就叫做可重入锁。同一个线程每次进入一次,锁的计数器都自增1,所以要等到锁的计数器下降为0时才能释放锁。

可重入锁的意义之一在于防止死锁。

代码简单实现,synchronized实现

  1. public class TestLock {
  2. public static synchronized void say() {
  3. System.out.println(Thread.currentThread().getName()+"\t invoke say");
  4. eat();
  5. }
  6. public synchronized static void eat() {
  7. System.out.println(Thread.currentThread().getName()+"\t invoke eat");
  8. }
  9. public static void main(String[] args) {
  10. new Thread(()->{
  11. say();
  12. },"t1").start();
  13. new Thread(()->{
  14. say();
  15. },"t2").start();
  16. }
  17. }

打印结果
202006062100484.png

ReentrantLock实现

  1. public class TestLock2 {
  2. private static Lock lock = new ReentrantLock();
  3. public static void say() {
  4. try {
  5. lock.lock();
  6. System.out.println(Thread.currentThread().getName()+"\t invoke say");
  7. eat();
  8. } finally {
  9. lock.unlock();
  10. }
  11. }
  12. public static void eat() {
  13. try {
  14. lock.lock();
  15. System.out.println(Thread.currentThread().getName()+"\t invoke eat");
  16. } finally {
  17. lock.unlock();
  18. }
  19. }
  20. public static void main(String[] args) {
  21. new Thread(()->{
  22. say();
  23. },"t1").start();
  24. new Thread(()->{
  25. say();
  26. },"t2").start();
  27. }
  28. }

打印结果
20200606210601903.png

可以看到,当方法eat也需要锁时,可以直接使用外层已经获取到的锁,而不用去等待重新获取锁。避免了去等待获取锁,从而造成死锁问题。

发表评论

表情:
评论列表 (有 0 条评论,492人围观)

还没有评论,来说两句吧...

相关阅读