当前位置: 代码迷 >> 综合 >> Semaphore 使用信号量控制对资源的N个副本的并发访问
  详细解决方案

Semaphore 使用信号量控制对资源的N个副本的并发访问

热度:54   发布时间:2024-02-08 12:44:00.0

目录

Semaphore:

主程序:

打印机组:


Semaphore:

这是一个计数器,用来控制N个共享资源的访问,这是一种基本的并发编程工具。

 

主程序:

该DEMO模拟20个任务,共享3个打印机的过程。并使其有序使用打印机。

package xyz.jangle.thread.test.n3_2.semaphore;/*** Semaphore DEMO 使用信号量控制对资源的N个副本的并发访问* 	该DEMO模拟20个任务,共享3个打印机的过程。并使其有序使用打印机。* * 	Semaphore的功能类型的同步锁的机制,但其区别是,其并发执行的数量并不限制为1个线程。* 	由 new Semaphore(3)参数3进行设置同步数量。* 	由 semaphore.acquire()来进行获取,acquire(2)可获取2个信号量。* 	由 semaphore.release()来进行释放,release(2)可释放2个信号量。* * * @author jangle* @email jangle@jangle.xyz* @time 2020年8月8日 下午4:47:53* */
public class M {public static void main(String[] args) {PrintQueue printQueue = new PrintQueue();for (int i = 0; i < 20; i++) {createThread(printQueue, i).start();}}/*** 创建线程* * @author jangle* @time 2020年8月8日 下午5:21:23* @param printQueue* @return*/private static Thread createThread(PrintQueue printQueue, int i) {return new Thread(() -> {System.out.println(Thread.currentThread().getName() + "开始执行");printQueue.printJob(new Object());System.out.println(Thread.currentThread().getName() + "完成执行");}, "Thread" + i);}}

打印机组:

模拟3台打印机,对外提供服务。

package xyz.jangle.thread.test.n3_2.semaphore;import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;/*** 	模拟3台打印机进行对外服务* @author jangle* @email jangle@jangle.xyz* @time 2020年8月8日 下午4:52:28* */
public class PrintQueue {// 信号量控制private final Semaphore semaphore;// 打印机组private final boolean freePrintes[];// 对获取打印机时,进行同步控制。private final Lock lockPrinters;public PrintQueue() {super();this.semaphore = new Semaphore(3);this.freePrintes = new boolean[3];for (int i = 0; i < freePrintes.length; i++) {freePrintes[i] = true;}this.lockPrinters = new ReentrantLock();}/*** 主要功能,使用信号量对现有打印机资源进行控制* * @author jangle* @time 2020年8月8日 下午4:57:30* @param document*/public void printJob(Object document) {try {// 获取访问许可(信号量)semaphore.acquire();int assignedPrinter = getPrinter();System.out.println("模拟打印... 打印机编号" + assignedPrinter + "。当前线程" + Thread.currentThread().getName());TimeUnit.SECONDS.sleep((long) (Math.random() * 10));freePrintes[assignedPrinter] = true;} catch (InterruptedException e) {e.printStackTrace();} finally {// 释放许可(信号量)semaphore.release();}}/*** 	获取打印机* * @author jangle* @time 2020年8月8日 下午5:18:20* @return*/private int getPrinter() {// 用于保存打印机编号int ret = -1;try {lockPrinters.lock();for (int i = 0; i < freePrintes.length; i++) {if (freePrintes[i]) {ret = i;freePrintes[i] = false;break;}}} catch (Exception e) {e.printStackTrace();} finally {lockPrinters.unlock();}return ret;}
}