Java并发编程使用 Semaphore 完成对资源的控制访问

最近在复习操作系统的时候,看到一个使用信号量的例子。
然后自己用java实现了一下,
本来还想用swing可视化一下的,后来想想就算了。。。

题目

  • 有一个仓库存放两种零件A和B,最大库容各为 m 个。
  • 有一个车间不断地取A和B进行装配, 每次各取一个。
  • 有两组供应商不断供应A和B (每次一个),
  • 为保证齐套和合理库存,当某种零件的数量比另一种的数量超过n (n < m) 个时,
  • 暂停对数量大的零件的进货,集中补齐少的零件。
  • 初始时仓库是空的。
  • m = 10, n = 3

代码及其注释已经很详细了。

package com.jsy.juc.thread_util;

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

/**
 * @Author: Song yang Ji
 * @ProjectName: learn-multiThread
 * @Version 1.0
 * @Description: 题目:有一个仓库存放两种零件A和B,最大库容各为 m 个。
 * 有一个车间不断地取A和B进行装配, 每次各取一个。
 * 有两组供应商不断供应A和B (每次一个),
 * 为保证齐套和合理库存,当某种零件的数量比另一种的数量超过n (n < m) 个时,
 * 暂停对数量大的零件的进货,集中补齐少的零件。
 * 初始时仓库是空的。
 * m = 10, n = 3
 * 仅使用信号量,不允许用synchronized、Lock,完成并发控制
 */


/**
 * 本题有6个约束关系,并记信号量分别为:
 * a >= 0, availASem = 0
 * b >= 0, availBSem = 0
 * a <= m, capacityASem = m
 * b <= m, capacityBSem= m
 * b - a <= n, baSem = n
 * a - b <= n, abSem = n
 */

public class SemaphoreExample {

    static final int M = 10, N = 3;

    // 6个信号量
    // 控制车间获取A、B的信号量
    static Semaphore availASem = new Semaphore(0), availBSem = new Semaphore(0);
    // 控制供应商提供零件的信号量
    static Semaphore capacityASem = new Semaphore(M), capacityBSem = new Semaphore(M);
    // 控制A与B差值的信号量
    static Semaphore baSem = new Semaphore(N), abSem = new Semaphore(N);

    // 0-1信号量,模拟互斥锁
    static Semaphore mutex = new Semaphore(1);

    static void consumer() {
        do {
            try {
                availASem.acquire();
                availBSem.acquire();
                mutex.acquire();
                // 注意这一步是不影响 A、B 差值
                System.out.println("生成车间取出零件 A、B 进行组装");
                TimeUnit.SECONDS.sleep(1);

                mutex.release();
                capacityASem.release();
                capacityBSem.release();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } while (true);
    }

    static void providerA() {
        do {
            try {
                capacityASem.acquire();
                abSem.acquire();
                mutex.acquire();

                System.out.println("供应商提供零件 A 放入仓库");
                TimeUnit.SECONDS.sleep(1);

                mutex.release();
                availASem.release();
                baSem.release();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } while (true);
    }

    static void providerB() {
        do {
            try {
                capacityBSem.acquire();
                baSem.acquire();
                mutex.acquire();

                System.out.println("供应商提供零件 B 放入仓库");
                TimeUnit.SECONDS.sleep(1);

                mutex.release();
                availBSem.release();
                abSem.release();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } while (true);
    }

    public static void main(String[] args) {
        new Thread(SemaphoreExample::consumer).start();
        new Thread(SemaphoreExample::providerA).start();
        new Thread(SemaphoreExample::providerB).start();
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值