信号量解决协调进程同步问题(司机与售票员问题)

发布时间 2023-10-23 22:28:09作者: 一往而深,
  • 问题描述(在日常生活中司机和售票员的行为动作需要满足一定的规则 )

分析并发进程的交互点

1.首先我们将司机和售票员看成是2个进程,他们需要协调配合完成工作
2.我们需要找到进行并发执行过程中的交互点(一个进行肯定要等另一个进程做了才能接着往下做),在这个点上我们需要使用P v操作让他们按照正确的顺序同步执行(如果让其异步执行可能很大可能会出现错误的结果)

  • 我们的期望情况
    要达到上面的目的我们希望是【如果启动车辆在关闭车门之前执行将进行等待】【打开车门在停下车辆之前执行将进行等待】

对于信号量使用的分析

1.从上图中可以看出来在这个过程中有2个规则,也就说明我们的进程有2个交互点需要同步
2.信号量表示可用资源的数量,我们需要他们最开始就可用进入等待状态,就只能将【信号量设置为0】表示没有资源,在另一个进行相应的动作将信号量+1才能进行执行

  • 实现图

    这个代码不能正确运行,原因待查正
  • Driver
package com.os;

public class Driver extends Thread{
    @Override
    public void run() {
        //司机的动作流程
        //1.车辆启动之前需要先关好门
        SemaphoreUtils.P1(SemaphoreUtils.semaphore1);//P
        System.out.println("启动车辆...");
        System.out.println("正常行驶...");
        System.out.println("到站停车...");
        //2.车停下后提示售票员开门
        SemaphoreUtils.V2(SemaphoreUtils.semaphore2);//V
    }
}

  • 售票员
package com.os;

public class TicketSeller extends Thread{

    @Override
    public void run() {
//售票员的动作流程
        System.out.println("关闭车门...");
        //1.关闭车门后提醒司机可用启动车辆
        SemaphoreUtils.V1(SemaphoreUtils.semaphore1);//v操作
        System.out.println("售票...");
        //2.要等车停下才能开门
        SemaphoreUtils.P2(SemaphoreUtils.semaphore2);//p操作
        System.out.println("打开车门...");

    }
}

  • 工具类
package com.os;

//提供互斥锁的方法
public class SemaphoreUtils {
public static int semaphore1 = 0;
    public static int semaphore2 = 0;
    //V操作
    public static void P1( int semaphore){
        while (semaphore<=0){//说明没有资源可用
            //自旋等待中

        }
        semaphore--;//信号量减1(标记资源用完了了
        semaphore1 = semaphore;
        System.out.println("semaphore1 = " + semaphore1);
    }
    //P操作
    public static void V1( int semaphore){
        semaphore++;//(标记资源可用了
        semaphore1 = semaphore;
        System.out.println("semaphore1 = " + semaphore1);
    }


    public static void P2( int semaphore){
        while (semaphore<=0){//说明没有资源可用
            //自旋等待中

        }
        semaphore--;//信号量减1(标记资源用完了了
        semaphore2 = semaphore;
        System.out.println("semaphore2 = " + semaphore2);
    }
    //P操作
    public static void V2( int semaphore){
        semaphore++;//(标记资源可用了
        semaphore2 = semaphore;
        System.out.println("semaphore2 = " + semaphore2);
    }
}
  • 测试类
package com.os;

public class SemaphoreTest {
    public static void main(String[] args) {
        Driver driver = new Driver();
        TicketSeller ticketSeller = new TicketSeller();
        driver.start();
        ticketSeller.start();
    }
}