JUC之可重入锁(递归锁)

一时失言乱红尘 2023-06-21 03:52 32阅读 0赞

可重入锁(又名递归锁)

理论

指的是同一线程外层函数获得锁之后,内层递归函数仍然能够获得该锁的代码

在同一个线程在外层方法获取锁的时候,在进入内层方法会自动获取锁

也就是说,线程可以进入任何一个它已经拥有的锁所同步着的代码块

ReentrantLock/synchronized就是一个典型的可重入锁

作用:避免死锁

代码

synchronized就是一个典型的可重入锁案例

  1. package Lock;
  2. //1.创建资源类
  3. class Phone{
  4. public synchronized void sendSMS()throws Exception{
  5. System.out.println(Thread.currentThread().getName() + "\t invoked sendSMS()");
  6. sendEmail();
  7. }
  8. public synchronized void sendEmail()throws Exception{
  9. System.out.println(Thread.currentThread().getName() + "\t ########invoked sendEmail()");
  10. }
  11. }
  12. public class ReenterLockDemo {
  13. //线程操作资源类
  14. public static void main(String[] args) throws Exception{
  15. Phone phone =new Phone();
  16. new Thread(() -> {
  17. try {
  18. phone.sendSMS();
  19. } catch (Exception e) {
  20. e.printStackTrace();
  21. }
  22. }, "t1").start();
  23. new Thread(() -> {
  24. try {
  25. phone.sendSMS();
  26. } catch (Exception e) {
  27. e.printStackTrace();
  28. }
  29. }, "t2").start();
  30. }
  31. }
  32. t1 invoked sendSMS() //t1线程在外层方法获取锁的时候
  33. t1 ########invoked sendEmail() //t1进入内层方法会自动获取锁
  34. t2 invoked sendSMS()
  35. t2 ########invoked sendEmail()
  36. Process finished with exit code 0

ReentrantLock就是一个典型的可重入锁

  1. package Lock;
  2. //1.创建资源类
  3. import java.util.concurrent.TimeUnit;
  4. import java.util.concurrent.locks.Lock;
  5. import java.util.concurrent.locks.ReentrantLock;
  6. class Phone implements Runnable{
  7. public synchronized void sendSMS()throws Exception{
  8. System.out.println(Thread.currentThread().getName() + "\t invoked sendSMS()");
  9. sendEmail();
  10. }
  11. public synchronized void sendEmail()throws Exception{
  12. System.out.println(Thread.currentThread().getName() + "\t ########invoked sendEmail()");
  13. }
  14. Lock lock=new ReentrantLock();
  15. @Override
  16. public void run(){
  17. get();
  18. }
  19. public void get(){
  20. lock.lock();//与下面的unlock对应
  21. lock.lock();
  22. try{
  23. System.out.println(Thread.currentThread().getName() + "\t ########invoked get()");
  24. set();
  25. }finally {
  26. lock.unlock();
  27. lock.unlock();
  28. }
  29. }
  30. public void set(){
  31. lock.lock();
  32. try {
  33. System.out.println(Thread.currentThread().getName() + "\t ########invoked set()");
  34. } finally {
  35. lock.unlock();
  36. }
  37. }
  38. }
  39. public class ReenterLockDemo {
  40. //线程操作资源类
  41. public static void main(String[] args) throws Exception{
  42. Phone phone =new Phone();
  43. new Thread(() -> {
  44. try {
  45. phone.sendSMS();
  46. } catch (Exception e) {
  47. e.printStackTrace();
  48. }
  49. }, "t1").start();
  50. new Thread(() -> {
  51. try {
  52. phone.sendSMS();
  53. } catch (Exception e) {
  54. e.printStackTrace();
  55. }
  56. }, "t2").start();
  57. //暂停一会儿线程
  58. try {
  59. TimeUnit.SECONDS.sleep(4); }catch (InterruptedException e){e.printStackTrace();}
  60. System.out.println();
  61. System.out.println();
  62. System.out.println();
  63. System.out.println();
  64. Thread t3 =new Thread(phone,"t3");
  65. Thread t4 =new Thread(phone,"t4");
  66. t3.start();
  67. t4.start();
  68. }
  69. }
  70. t1 invoked sendSMS()
  71. t1 ########invoked sendEmail()
  72. t2 invoked sendSMS()
  73. t2 ########invoked sendEmail()
  74. t3 ########invoked get()
  75. t3 ########invoked set()
  76. t4 ########invoked get()
  77. t4 ########invoked set()
  78. Process finished with exit code 0

发表评论

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

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

相关阅读

    相关 ()

    可重入锁 synchronized 和Lock都是可重入锁,也叫递归锁,即一个线程可以重复获取同一把锁 是指在同一个线程在外层方法获取锁的时候,再进入该线程的内层方法会

    相关 与非

    可重入锁与非可重入锁 可重入锁又称递归锁,是指同一个线程在外层方法获取锁的时候,再进入该线程的内层方法会自动获取锁(前提是锁对象得是同一个对象),不会因为之前已经获