题目描述: 一条河上架设了由N个桥墩组成的一座桥。若一个桥墩只能站一个人,过河的人只能沿着桥向前走而不能向后退。 过河时,只要对岸无人过,就可以过。 但不允许河对岸的两个人同时过,以防止出现死锁。 请给出两个方向的人顺利过河的同步算法。 (可以简单扩充为多个方向上一个环形的桥 实现简单的给两个方向)
思路如下: 第一个上桥的人获取桥的互斥信号量,最后一个上桥的人释放桥的互斥信号量 对于一个方向设立一个计数器,同时设立该计数器的互斥信号量 还有一个信号量是限制桥上最多的人数
代码如下:
package ConcurrentControl;
import java.util.Random;
import java.util.concurrent.Semaphore;
/**
题目描述:
一条河上架设了由N个桥墩组成的一座桥。若一个桥墩只能站一个人,过河的人只能沿着桥向前走而不能向后退。
过河时,只要对岸无人过,就可以过。
但不允许河对岸的两个人同时过,以防止出现死锁。
请给出两个方向的人顺利过河的同步算法。
(可以简单扩充为多个方向上一个环形的桥 实现简单的给两个方向)
思路如下:
第一个上桥的人获取桥的互斥信号量,最后一个上桥的人释放桥的互斥信号量
对于一个方向设立一个计数器,同时设立该计数器的互斥信号量
还有一个信号量是限制桥上最多的人数
*/
public class Problem_04 {
public static void main(String argv[]){
test();
}
public static void test(){
Random random = new Random(2);//指定种子数字
for(int i=0; i<20; i++){
int randNum = random.nextInt();
boolean isPositive = true;
if(randNum>0)
isPositive = false;
new Thread(new Passer(isPositive)).start();
}
}
private static class Container{
// 获取桥的互斥信号量
public static Semaphore bridgeMutex = new Semaphore(1);
// 限制桥上人数的信号量
public static Semaphore numOfPasserOnBridge = new Semaphore(3);
// 正方向的计数器
public static int cntPositive = 0;
// 正方向计数器互斥信号量
public static Semaphore cntPositiveMutex = new Semaphore(1);
// 负方向的计数器
public static int cntNegative = 0;
// 负方向计数器互斥信号量
public static Semaphore cntNegativeMutex = new Semaphore(1);
}
private static class Passer implements Runnable{
boolean isPositive = true;
Passer(boolean isPositive){
this.isPositive = isPositive;
}
private void cross(){
System.out.printf(Thread.currentThread().getName()+" -> "+this.isPositive+"\n");
}
@Override
public void run() {
if(isPositive){
// 判断是否第一个上桥
try {
Container.cntPositiveMutex.acquire();
Container.cntPositive++;
if(Container.cntPositive==1){
System.out.printf("********************\n");
Container.bridgeMutex.acquire();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
Container.cntPositiveMutex.release();
}
// 执行cross操作
try {
Container.numOfPasserOnBridge.acquire();
cross();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
Container.numOfPasserOnBridge.release();
}
// 判断是否最后一个人离开桥
try {
Container.cntPositiveMutex.acquire();
Container.cntPositive--;
if(Container.cntPositive==0){
Container.bridgeMutex.release();
System.out.printf("********************\n");
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
Container.cntPositiveMutex.release();
}
}
else{
// 判断是否第一个上桥
try {
Container.cntNegativeMutex.acquire();
Container.cntNegative++;
if(Container.cntNegative==1){
System.out.printf("********************\n");
Container.bridgeMutex.acquire();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
Container.cntNegativeMutex.release();
}
// 执行cross操作
try {
Container.numOfPasserOnBridge.acquire();
cross();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
Container.numOfPasserOnBridge.release();
}
// 判断是否最后一个人离开桥
try {
Container.cntNegativeMutex.acquire();
Container.cntNegative--;
if(Container.cntNegative==0){
Container.bridgeMutex.release();
System.out.printf("********************\n");
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
Container.cntNegativeMutex.release();
}
}
}
}
}