600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > Java并发编程中级篇(二):使用Semaphore信号量进行多个资源并发控制

Java并发编程中级篇(二):使用Semaphore信号量进行多个资源并发控制

时间:2021-07-23 12:27:00

相关推荐

Java并发编程中级篇(二):使用Semaphore信号量进行多个资源并发控制

独角兽企业重金招聘Python工程师标准>>>

上一节中我们使用了Semaphore信号量保护共享资源,但是它只能保护一个共享资源,当我们需要同时保护多个共享资源的时候,我们只需要在创建信号量的时候使用new Semaphore(int)构造方法,传入参数是你想要保护的共享资源数目。

/*** Creates a {@code Semaphore} with the given number of* permits and nonfair fairness setting.** @param permits the initial number of permits available.* This value may be negative, in which case releases* must occur before any acquires will be granted.*/public Semaphore(int permits) {sync = new NonfairSync(permits);}

还是PrintQueue的例子,我们把打印队列中打印机数目增加到3台,使用一个boolean[3]数组来标记打印机是否可用,同时使用3个信号量来保证这三个打印机的并发访问控制。定义一个锁来保证更改打印机状态的时候的同步控制。获取打印机资源的时候记录打印机ID,并标记打印机处于使用状态。释放打印机资源的时候,把相应ID的打印机状态置为可用。

public class PrintQueue {private boolean freePrinters[];private Lock lockPrinters;private Semaphore semaphore;public PrintQueue() {this.freePrinters = new boolean[3];this.lockPrinters = new ReentrantLock();this.semaphore = new Semaphore(3);for (int i = 0; i < 3; i++) {this.freePrinters[i] = true;}}public void printJob(Object object) {try {semaphore.acquire();int assignedPrinter = getPrinter();long duration = (long)(Math.random() * 10);System.out.printf("%s: Print a Job in printer %d duration %d seconds.\n",Thread.currentThread().getName(), assignedPrinter, duration);TimeUnit.SECONDS.sleep(duration);freePrinter(assignedPrinter);} catch (InterruptedException e) {e.printStackTrace();} finally {semaphore.release();}}private int getPrinter() {lockPrinters.lock();int printNo = -1;try {for (int i = 0; i < freePrinters.length; i++) {if (freePrinters[i]) {printNo = i;freePrinters[i] = false;break;}}} finally {lockPrinters.unlock();}return printNo;}private void freePrinter(int printNo) {lockPrinters.lock();try {freePrinters[printNo] = true;} finally {lockPrinters.unlock();}}

打印Job线程类和主方法类不变

public class Job implements Runnable{private PrintQueue printQueue;public Job(PrintQueue printQueue) {this.printQueue = printQueue;}@Overridepublic void run() {System.out.printf("%s: Going to print a Job.\n", Thread.currentThread().getName());printQueue.printJob(new Object());System.out.printf("%s: The Job has been printed.\n", Thread.currentThread().getName());}}

public class Main {public static void main(String[] args) {PrintQueue printQueue = new PrintQueue();Thread[] threads = new Thread[10];for (int i = 1; i < 10; i++) {threads[i] = new Thread(new Job(printQueue));}for (int i = 1; i < 10; i++) {threads[i].start();}}}

执行查看控制台日志,你可以发现每次有三个打印Job可以执行。

Thread-0: Going to print a Job.Thread-8: Going to print a Job.Thread-7: Going to print a Job.Thread-6: Going to print a Job.Thread-5: Going to print a Job.Thread-4: Going to print a Job.Thread-3: Going to print a Job.Thread-2: Going to print a Job.Thread-1: Going to print a Job.Thread-8: Print a Job in printer 1 duration 2 seconds.Thread-7: Print a Job in printer 2 duration 6 seconds.Thread-0: Print a Job in printer 0 duration 2 seconds.Thread-0: The Job has been printed.Thread-5: Print a Job in printer 1 duration 7 seconds.Thread-6: Print a Job in printer 0 duration 9 seconds.Thread-8: The Job has been printed.Thread-7: The Job has been printed.Thread-4: Print a Job in printer 2 duration 1 seconds.Thread-4: The Job has been printed.Thread-3: Print a Job in printer 2 duration 6 seconds.Thread-5: The Job has been printed.Thread-2: Print a Job in printer 1 duration 7 seconds.Thread-6: The Job has been printed.Thread-1: Print a Job in printer 0 duration 2 seconds.Thread-3: The Job has been printed.Thread-1: The Job has been printed.Thread-2: The Job has been printed.

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。