解锁是如何在等待之后发生的

huangapple go评论100阅读模式
英文:

How is unlock happening after await

问题

我写了一个小程序来交替打印奇偶数,但有一个问题:

由于线程在await调用处应该等待,那么可重入锁是如何被解锁的?

  1. public class Worker implements Runnable
  2. {
  3. private ReentrantLock rLock = null;
  4. private Condition condition = null;
  5. private String name;
  6. volatile static boolean isEvenTurn = true;
  7. public Worker(String name, ReentrantLock rLock, Condition condition)
  8. {
  9. this.name = name;
  10. this.rLock = rLock;
  11. this.condition = condition;
  12. }
  13. @Override
  14. public void run()
  15. {
  16. try
  17. {
  18. if(name.equals("ODD"))
  19. printOdd();
  20. else
  21. printEven();
  22. }
  23. catch(Exception e) { e.printStackTrace();}
  24. }
  25. private void printOdd() throws Exception
  26. {
  27. while(isEvenTurn);
  28. for(int i=1;i<10;i+=2)
  29. {
  30. try
  31. {
  32. rLock.lock();
  33. System.out.println(i);
  34. }
  35. catch(Exception e) {e.printStackTrace();}
  36. finally
  37. {
  38. condition.signal();
  39. condition.await();
  40. rLock.unlock();
  41. }
  42. }
  43. }
  44. private void printEven() throws Exception
  45. {
  46. for(int i=0;i<10;i+=2)
  47. {
  48. try
  49. {
  50. rLock.lock();
  51. System.out.println(i);
  52. isEvenTurn = false;
  53. }
  54. catch(Exception e) {e.printStackTrace();}
  55. finally
  56. {
  57. condition.signal();
  58. condition.await();
  59. rLock.unlock();
  60. }
  61. }
  62. }
  63. public static void main(String[] args)
  64. {
  65. ReentrantLock rLock = new ReentrantLock();
  66. ExecutorService service = Executors.newFixedThreadPool(2);
  67. Condition c = rLock.newCondition();
  68. Worker oddPrinter = new Worker("ODD",rLock,c);
  69. Worker evenPrinter = new Worker("EVEN",rLock,c);
  70. service.execute(evenPrinter);
  71. service.execute(oddPrinter);
  72. service.shutdown();
  73. }
  74. }
英文:

I wrote a small program to print odd-even numbers alternatively but have a question:

Since thread should wait at await call so how is reentrant lock is getting unlocked?

  1. public class Worker implements Runnable
  2. {
  3. private ReentrantLock rLock = null;
  4. private Condition condition = null;
  5. private String name;
  6. volatile static boolean isEvenTurn = true;
  7. public Worker(String name, ReentrantLock rLock, Condition condition)
  8. {
  9. this.name = name;
  10. this.rLock = rLock;
  11. this.condition = condition;
  12. }
  13. @Override
  14. public void run()
  15. {
  16. try
  17. {
  18. if(name.equals(&quot;ODD&quot;))
  19. printOdd();
  20. else
  21. printEven();
  22. }
  23. catch(Exception e) { e.printStackTrace();}
  24. }
  25. private void printOdd() throws Exception
  26. {
  27. while(isEvenTurn);
  28. for(int i=1;i&lt;10;i+=2)
  29. {
  30. try
  31. {
  32. rLock.lock();
  33. System.out.println(i);
  34. }
  35. catch(Exception e) {e.printStackTrace();}
  36. finally
  37. {
  38. condition.signal();
  39. condition.await();
  40. rLock.unlock();
  41. }
  42. }
  43. }
  44. private void printEven() throws Exception
  45. {
  46. for(int i=0;i&lt;10;i+=2)
  47. {
  48. try
  49. {
  50. rLock.lock();
  51. System.out.println(i);
  52. isEvenTurn = false;
  53. }
  54. catch(Exception e) {e.printStackTrace();}
  55. finally
  56. {
  57. condition.signal();
  58. condition.await();
  59. rLock.unlock();
  60. }
  61. }
  62. }
  63. public static void main(String[] args)
  64. {
  65. ReentrantLock rLock = new ReentrantLock();
  66. ExecutorService service = Executors.newFixedThreadPool(2);
  67. Condition c = rLock.newCondition();
  68. Worker oddPrinter = new Worker(&quot;ODD&quot;,rLock,c);
  69. Worker evenPrinter = new Worker(&quot;EVEN&quot;,rLock,c);
  70. service.execute(evenPrinter);
  71. service.execute(oddPrinter);
  72. service.shutdown();
  73. }
  74. }

答案1

得分: 2

在printEven()方法中添加以下代码:在finally块中:

  1. finally
  2. {
  3. condition.signal();
  4. if (i < 10) condition.await();
  5. rLock.unlock();
  6. }
  7. 通过添加这个条件,当i = 10时,你的线程将不再等待。
英文:

In printEven() method add this line: in finally block:

  1. finally
  2. {
  3. condition.signal();
  4. if(i &lt; 10)condition.await();
  5. rLock.unlock();
  6. }

By adding this condition, when your
i = 10 your thread will not wait anymore.

huangapple
  • 本文由 发表于 2020年9月3日 12:29:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/63716866.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定