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

2014-04-27 19:26

题目:哲学家吃饭问题,死锁问题经典模型(专门用来黑哲学家的?)。

解法:死锁四条件:1. 资源互斥。2. 请求保持。3. 非抢占。4.
循环等待。所以,某砖家拿起一只筷子后如果发现没有另一只了,就必须把手里这只筷子放下,这应该是通过破坏“请求保持”原则来防止死锁产生,请求资源失败时,连自己的资源也进一步释放,然后在下一轮里继续请求,直到成功执行。

代码:


 1 // This is the class for chopsticks.
2 import java.util.concurrent.locks.Lock;
3 import java.util.concurrent.locks.ReentrantLock;
4
5 public class Chopstick {
6 private Lock lock;
7
8 public Chopstick() {
9 lock = new ReentrantLock();
10 }
11
12 public boolean pickUp() {
13 return lock.tryLock();
14 }
15
16 public void putDown() {
17 lock.unlock();
18 }
19 }
20
21 //------------------------------------I‘m a delimiter------------------------------------
22 // This is the class for philosophers.
23 import java.util.Vector;
24
25 public class Philosopher extends Thread {
26 private Chopstick left;
27 private Chopstick right;
28 private int id;
29 int appetite;
30
31 final int FULL_APPETITE = 10;
32
33 public Philosopher(Chopstick left, Chopstick right, int id) {
34 // TODO Auto-generated constructor stub
35 appetite = 0;
36 this.left = left;
37 this.right = right;
38 this.id = id;
39 }
40
41 private boolean pickUp() {
42 if (!left.pickUp()) {
43 return false;
44 }
45 if (!right.pickUp()) {
46 left.putDown();
47 return false;
48 }
49 return true;
50 }
51
52 private void putDown() {
53 left.putDown();
54 right.putDown();
55 }
56
57 public boolean eat() {
58 while (appetite < FULL_APPETITE) {
59 if (!pickUp()) {
60 return false;
61 }
62 System.out.println(id + ":chew~");
63 ++appetite;
64 putDown();
65 }
66 return appetite == FULL_APPETITE;
67 }
68
69 @Override
70 public void run() {
71 // TODO Auto-generated method stub
72 super.run();
73 while (!eat()) {
74 // Not full yet.
75 }
76 }
77
78 public static void main(String[] args) {
79 final int n = 6;
80 Vector<Chopstick> chopsticks = new Vector<Chopstick>();
81 Vector<Philosopher> philosophers = new Vector<Philosopher>();
82
83 for (int i = 0; i < n; ++i) {
84 chopsticks.add(new Chopstick());
85 }
86 for (int i = 0; i < n; ++i) {
87 philosophers.add(new Philosopher(chopsticks.elementAt(i),
88 chopsticks.elementAt((i + 1) % n), i + 1));
89 }
90
91 for (int i = 0; i < n; ++i) {
92 philosophers.elementAt(i).start();
93 }
94 }
95 }

《Cracking the Coding Interview》——第16章:线程与锁——题目3,码迷,mamicode.com

时间: 2025-01-14 09:17:10

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

《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

《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