《Cracking the Coding Interview》——第16章:线程与锁——题目5
2014-04-27 20:25
357 查看
2014-04-27 20:16
题目:假设一个类Foo有三个公有的成员方法first()、second()、third()。请用锁的方法来控制调用行为,使得他们的执行循序总是遵从first、second、third的顺序。
解法:你应该想到了用lock的方法类阻塞,不过这里面有个概念问题使得直接用ReentrantLock不能通过编译(对于一个锁对象,不同在A线程中锁定,又在B线程中解锁,不允许这样的归属关系),可以用Semaphore来达到相同的目的。请看下面的代码。
代码:
题目:假设一个类Foo有三个公有的成员方法first()、second()、third()。请用锁的方法来控制调用行为,使得他们的执行循序总是遵从first、second、third的顺序。
解法:你应该想到了用lock的方法类阻塞,不过这里面有个概念问题使得直接用ReentrantLock不能通过编译(对于一个锁对象,不同在A线程中锁定,又在B线程中解锁,不允许这样的归属关系),可以用Semaphore来达到相同的目的。请看下面的代码。
代码:
// 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? public class FirstRun implements Runnable { private FooBar fooBar; public FirstRun(FooBar fooBar) { // TODO Auto-generated constructor stub this.fooBar = fooBar; } @Override public void run() { // TODO Auto-generated method stub fooBar.first(); } } // ----------------------------------------------------------------------------- public class SecondRun implements Runnable { private FooBar fooBar; public SecondRun(FooBar fooBar) { // TODO Auto-generated constructor stub this.fooBar = fooBar; } @Override public void run() { // TODO Auto-generated method stub fooBar.second(); } } // ----------------------------------------------------------------------------- public class ThirdRun implements Runnable { private FooBar fooBar; public ThirdRun(FooBar fooBar) { // TODO Auto-generated constructor stub this.fooBar = fooBar; } @Override public void run() { // TODO Auto-generated method stub fooBar.third(); } } // ----------------------------------------------------------------------------- import java.util.concurrent.Semaphore; public class FooBar { private Semaphore sem1; private Semaphore sem2; private Semaphore sem3; public FooBar() { // TODO Auto-generated constructor stub sem1 = new Semaphore(1); sem2 = new Semaphore(1); sem3 = new Semaphore(1); try { sem1.acquire(); sem2.acquire(); sem3.acquire(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void first() { System.out.println("first"); sem1.release(); } public void second() { try { sem1.acquire(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } sem1.release(); System.out.println("second"); sem2.release(); } public void third() { try { sem2.acquire(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } sem2.release(); System.out.println("third"); sem3.release(); } public static void main(String[] args) { FooBar fooBar = new FooBar(); Thread t1 = new Thread(new FirstRun(fooBar)); Thread t2 = new Thread(new SecondRun(fooBar)); Thread t3 = new Thread(new ThirdRun(fooBar)); t3.start(); t1.start(); t2.start(); } }
相关文章推荐
- 《Cracking the Coding Interview》——第16章:线程与锁——题目6
- 《Cracking the Coding Interview》——第16章:线程与锁——题目1
- 《Cracking the Coding Interview》——第16章:线程与锁——题目2
- 《Cracking the Coding Interview》——第16章:线程与锁——题目3
- 《Cracking the Coding Interview》——第16章:线程与锁——题目4
- 《Cracking the Coding Interview》——第17章:普通题——题目3
- 《Cracking the Coding Interview》——第17章:普通题——题目10
- 《Cracking the Coding Interview》——第18章:难题——题目8
- 《Cracking the Coding Interview》——第1章:数组和字符串——题目7
- 《Cracking the Coding Interview》——第4章:树和图——题目8
- 《Cracking the Coding Interview》——第6章:智力题——题目3
- 《Cracking the Coding Interview》——第9章:递归和动态规划——题目5
- 《Cracking the Coding Interview》——第8章:面向对象设计——题目3
- 《Cracking the Coding Interview》——第8章:面向对象设计——题目10
- 《Cracking the Coding Interview》——第10章:可扩展性和存储空间限制——题目3
- 《Cracking the Coding Interview》——第18章:难题——题目9
- 《Cracking the Coding Interview》——第1章:数组和字符串——题目8
- 《Cracking the Coding Interview》——第4章:树和图——题目9
- 《Cracking the Coding Interview》——第6章:智力题——题目4
- 《Cracking the Coding Interview》——第9章:递归和动态规划——题目6