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 }