信号量的PV操作实例

问题描述
  A地和B地之间有一条弯曲的路,其中的每一段路每次只允许一辆自行车通过,且每个方向每次只允许一人通过,但中间有一个”安全岛“(同时允许两辆自行车停留),可供两辆自行车已从两端进人小路情况下错车使用,请设计一个算法使来往的自行车均可顺利通过。


问题分析
  首先有两个线程,表示从A地到B地,和从B地到A地,那么需要设置几个信号量呢?拿从A到B来说,因为一个方向一次只能过一个人,所以在一个人没到B地之前,都不能有人从A出发,所以需要对这设置一个信号量 ,然后从A地到安全岛之前有一段路,可能这段路被从A到B的人占据,也可能被从B到A的人占据,所以需要对这段路设置一个信号量。同理,从B到A也需要设置这样两个信号量。这是可能会有人想,安全岛只能容纳两个人,要不要对安全岛也设置一个信号量,其实是不需要的。因为一个方向一次只能过一个人,所以在任何时刻,路上最多也两个人,所以不需要对安全岛设置信号量。

问题解决

import java.util.concurrent.Semaphore;
public class JcMain {

        private Semaphore mSemaphoreATB = new Semaphore(1);  //从A到B的信号量
        private Semaphore mSemaphoreBTA = new Semaphore(1);  //从B到A的信号量
        private Semaphore mSemaphoreRoadA = new Semaphore(1);  //RoadA的信号量
        private Semaphore mSemaphoreRoadB = new Semaphore(1);  //RoadB的信号量
        public static void main(String[] args) {
            JcMain jcMain = new JcMain();
            jcMain.begin();
        }

        void begin(){
                while(true){
                    start();
                }
        }

        void start(){
                Thread ATBThread = new Thread(new Runnable(){
                    public void run() {
                                    try {
                                        mSemaphoreATB.acquire(); //获得从A到B的信号
                                        mSemaphoreRoadA.acquire(); //获得Road的信号
                                        System.out.println("A-B:通过RoadA,进入安全岛");
                                        mSemaphoreRoadA.release();
                                        mSemaphoreRoadB.acquire();  //获得RoadB的信号
                                        System.out.println("A-B:通过RoadB,到达B");
                                        mSemaphoreATB.release();  //释放从A到B的信号
                                        mSemaphoreRoadB.release();  //释放RoadB的信号
                                    } catch (InterruptedException e) {} 
                            }
                });
                Thread BTAThread = new Thread(new Runnable(){
                    public void run() {
                                    try {
                                        mSemaphoreBTA.acquire(); //获得从B到A的信号
                                        mSemaphoreRoadB.acquire(); //获得Road的信号
                                        System.out.println("B-A:通过RoadB,进入安全岛");
                                        mSemaphoreRoadB.release();
                                        mSemaphoreRoadA.acquire();  //获得RoadB的信号
                                        System.out.println("B-A:通过RoadA,到达A");
                                        mSemaphoreBTA.release();  //释放从A到B的信号
                                        mSemaphoreRoadA.release();  //释放RoadB的信号
                                    } catch (InterruptedException e) {} 
                            }
                });

                ATBThread.start();
                BTAThread.start();
        }
}

运行结果

A-B:通过RoadA,进入安全岛
A-B:通过RoadB,到达B
A-B:通过RoadA,进入安全岛
B-A:通过RoadB,进入安全岛
B-A:通过RoadA,到达A
A-B:通过RoadB,到达B
A-B:通过RoadA,进入安全岛
A-B:通过RoadB,到达B
A-B:通过RoadA,进入安全岛
A-B:通过RoadB,到达B
B-A:通过RoadB,进入安全岛
B-A:通过RoadA,到达A

  从运行结果可以看到,这是没有问题的。


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值