《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 }

《Cracking the Coding Interview》——第16章:线程与锁——题目5,布布扣,bubuko.com

时间: 2024-11-03 05:33:01

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

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

2014-04-27 19:26 题目:哲学家吃饭问题,死锁问题经典模型(专门用来黑哲学家的?). 解法:死锁四条件:1. 资源互斥.2. 请求保持.3. 非抢占.4. 循环等待.所以,某砖家拿起一只筷子后如果发现没有另一只了,就必须把手里这只筷子放下,这应该是通过破坏"请求保持"原则来防止死锁产生,请求资源失败时,连自己的资源也进一步释放,然后在下一轮里继续请求,直到成功执行. 代码: 1 // This is the class for chopsticks. 2 import j

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

2014-04-27 19:14 题目:如何测量上下文切换的时间? 解法:首先,上下文切换是什么,一搜就知道.对于这么一个极短的时间,要测量的话,可以通过放大N倍的方法.比如:有A和B两件事,并且经常一起发生,每件只需要花几纳秒.如果你把A事件连续做几百万次,而B时间只做了几次,这样就能排除B事件对于测量的影响.如果总时间S = mA + nB.当m >> n 时,A≈S / m.下面的测量方法类似于打乒乓球,在主线程和副线程间互相传递一个令牌,这个令牌可以是变量.管道之类的用于通信的工具.与

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

2014-04-27 19:09 题目:线程和进程有什么区别? 解法:理论题,操作系统教材上应该有很详细的解释.我回忆了一下,写了如下几点. 代码: 1 // 16.1 What is the difference between process and thread? 2 Answer: 3 Process: 4 1. Basic element of resource allocation in the operating system. 5 2. Possesses independent

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

2014-04-27 20:25 题目:关于java中标有synchronized的成员方法? 解法:这代表同一个对象实例的synchronized方法不能被多个线程同时调用.注意有这么多个地方都加粗了,如果这些条件有一个不满足的话,就是可以调用的.另外,如果此方法是静态成员方法, 那么总可以认为是"同一实例"的,因为静态方法就属于一个类,类似于单体. 代码: 1 // 16.6 How do you explain the "synchronized" keywo

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

2014-04-27 20:06 题目:设计一个类,只有在不产生死锁的时候才分配资源. 解法:不太清楚这个题是要分配何种资源,以何种形式?所以没能动手写个可运行的代码,只是闲扯了几句理论分析. 代码: 1 // 16.4 Design a class which provides a lock only if no deadlock would take place. 2 1. The class will maintain a list of all locks that would be r

《Cracking the Coding Interview》——第18章:难题——题目10

2014-04-29 04:22 题目:给定一堆长度都相等的单词,和起点.终点两个单词,请从这堆单词中寻找一条变换路径,把起点词变成终点词,要求每次变换只能改一个字母. 解法:Leetcode中有Word Ladder,这题基本思路一致. 代码: 1 // 18.10 Given a list of words, all of same length. Given a source and a destionation words, you have to check if there exis

《Cracking the Coding Interview》——第18章:难题——题目9

2014-04-29 04:18 题目:有一连串的数被读入,设计一个数据结构,能随时返回当前所有数的中位数. 解法:用一个大顶堆,一个小顶堆将数分成数量最接近的两份,就能轻松得到中位数了. 代码: 1 // 18.9 A stream of integers are passed to you, you have to tell me the median as they keep coming in. 2 #include <climits> 3 #include <iostream&

《Cracking the Coding Interview》——第18章:难题——题目13

2014-04-29 04:40 题目:给定一个字母组成的矩阵,和一个包含一堆单词的词典.请从矩阵中找出一个最大的子矩阵,使得从左到右每一行,从上到下每一列组成的单词都包含在词典中. 解法:O(n^3)级别的时间和空间进行动态规划.这道题目和第17章的最后一题很像,由于这题的时间复杂度实在是高,我动手写了字典树进行加速.如果单纯用哈希表来作为词典,查询效率实际会达到O(n)级别,导致最终的算法复杂度为O(n^4).用字典树则可以加速到O(n^3),因为对于一个字符串"abcd",只需要

《Cracking the Coding Interview》——第18章:难题——题目11

2014-04-29 04:30 题目:给定一个由'0'或者'1'构成的二维数组,找出一个四条边全部由'1'构成的正方形(矩形中间可以有'0'),使得矩形面积最大. 解法:用动态规划思想,记录二维数组每个元素向上下左右四个方向各有多少个连续的'1',然后用O(n^3)时间计算出满足条件的最大正方形.时间复杂度O(n^3),空间复杂度O(n^2). 代码: 1 // 18.11 Given an NxN matrix of 0s and 1s, find out a subsquare whose