多线程并发
模拟避免死锁的哲学家进餐问题
来自 《Cracking Coding Interview 6th Programming》
筷子:
class Chopstick {
private Lock lock;
public Chopstick() {
lock = new ReentrantLock();
}
public void pickUp() {
lock.lock();
}
public void putDown() {
lock.unlock();
}
}
哲学家:
class Philosopher extends Thread {
private int bites = 10;
private Chopstick left, right;
public Philosopher(Chopstick left, Chopstick right) {
this.left = left;
this.right = right;
}
public void eat() {
pickUp();
chew();
putDown();
}
public void pickUp() {
left.pickUp();
right.pickUp();
}
public void chew() {}
public void putDown() {
right.putDown();
left.putDown();
}
public void run() {
for (int i = 0; i < bites; i++) {
eat();
}
}
}
上述代码,当所有哲学家都同时拿起左边筷子,等待右边筷子的时候,将会出现死锁。
All or Nothing
如果一个哲学家无法获取右侧的筷子,那么他会放下左侧的筷子。
class Chopstick {
// 其余代码相同
public void pickUp() {
lock.tryLock();
}
}
class Philosopher extends Thread {
public void eat() {
if (pickUp()) {
chew();
putDown();
}
}
public boolean pickUp() {
if (!left.pickUp()) {
return false;
}
if (!right.pickUp()) {
left.putDown();
return false;
}
return true;
}
}
顺序访问
A lock in Java is owned by the same thread which locked it .
Semaphore
public class Foo {
public Semaphore sem1, sem2;
public Foo() {
try {
sem1 = new Semaphore(1);
sem2 = new Semaphore(1);
sem1.acquire();
sem2.acquire();
} catch (...) {
...
}
}
public void first() {
try {
...
sem1.release();
} catch (...) {
...
}
}
public void second() {
try {
sem1.acquire();
sem1.release();
...
sem2.release();
} catch (...) {
...
}
}
public void third() {
try {
sem2.acquire();
sem2.release();
...
} catch (...) {
...
}
}
}