首页 > 代码库 > 《Cracking the Coding Interview》——第16章:线程与锁——题目5

《Cracking the Coding Interview》——第16章:线程与锁——题目5

2014-04-27 20:16

题目:假设一个类Foo有三个公有的成员方法first()、second()、third()。请用锁的方法来控制调用行为,使得他们的执行循序总是遵从first、second、third的顺序。

解法:你应该想到了用lock的方法类阻塞,不过这里面有个概念问题使得直接用ReentrantLock不能通过编译(对于一个锁对象,不同在A线程中锁定,又在B线程中解锁,不允许这样的归属关系),可以用Semaphore来达到相同的目的。请看下面的代码。

代码:

  1 // 16.5 There‘re three methods in a class FooBar, how would you make sure that they‘re executed in a fixed order, in whichever order they‘re called?
  2 public class FirstRun implements Runnable {
  3     private FooBar fooBar;
  4     
  5     public FirstRun(FooBar fooBar) {
  6         // TODO Auto-generated constructor stub
  7         this.fooBar = fooBar;
  8     }
  9     
 10     @Override
 11     public void run() {
 12         // TODO Auto-generated method stub
 13         fooBar.first();
 14     }
 15 }
 16 
 17 // -----------------------------------------------------------------------------
 18 public class SecondRun implements Runnable {
 19     private FooBar fooBar;
 20     
 21     public SecondRun(FooBar fooBar) {
 22         // TODO Auto-generated constructor stub
 23         this.fooBar = fooBar;
 24     }
 25     
 26     @Override
 27     public void run() {
 28         // TODO Auto-generated method stub
 29         fooBar.second();
 30     }
 31 }
 32 
 33 // -----------------------------------------------------------------------------
 34 public class ThirdRun implements Runnable {
 35     private FooBar fooBar;
 36     
 37     public ThirdRun(FooBar fooBar) {
 38         // TODO Auto-generated constructor stub
 39         this.fooBar = fooBar;
 40     }
 41     
 42     @Override
 43     public void run() {
 44         // TODO Auto-generated method stub
 45         fooBar.third();
 46     }
 47 }
 48 
 49 // -----------------------------------------------------------------------------
 50 import java.util.concurrent.Semaphore;
 51 
 52 public class FooBar {
 53     private Semaphore sem1;
 54     private Semaphore sem2;
 55     private Semaphore sem3;
 56     
 57     public FooBar() {
 58         // TODO Auto-generated constructor stub
 59         sem1 = new Semaphore(1);
 60         sem2 = new Semaphore(1);
 61         sem3 = new Semaphore(1);
 62         
 63         try {
 64             sem1.acquire();
 65             sem2.acquire();
 66             sem3.acquire();
 67         } catch (InterruptedException e) {
 68             // TODO Auto-generated catch block
 69             e.printStackTrace();
 70         }
 71     }
 72 
 73     public void first() {
 74         System.out.println("first");
 75         
 76         sem1.release();
 77     }
 78 
 79     public void second() {
 80         try {
 81             sem1.acquire();
 82         } catch (InterruptedException e) {
 83             // TODO Auto-generated catch block
 84             e.printStackTrace();
 85         }
 86         sem1.release();
 87         System.out.println("second");
 88         sem2.release();
 89     }
 90 
 91     public void third() {
 92         try {
 93             sem2.acquire();
 94         } catch (InterruptedException e) {
 95             // TODO Auto-generated catch block
 96             e.printStackTrace();
 97         }
 98         sem2.release();
 99         System.out.println("third");
100         sem3.release();
101     }
102 
103     public static void main(String[] args) {
104         FooBar fooBar = new FooBar();
105         Thread t1 = new Thread(new FirstRun(fooBar));
106         Thread t2 = new Thread(new SecondRun(fooBar));
107         Thread t3 = new Thread(new ThirdRun(fooBar));
108         
109         t3.start();
110         t1.start();
111         t2.start();
112     }
113 }