Java并发编程-11-线程同步辅助类-semaphore
来源:互联网 发布:oracle数据库存年份 编辑:程序博客网 时间:2024/05/22 02:12
一、更高级的同步机制
三、注意
四、其他方法
- 信号量Semaphore:是一种计数器,用来保护一个或多个共享资源的访问。
- CountDownLatch:在完成一组正在其他线程中执行的操作之前,它允许线程一直等待
- CyclicBarrier:它允许多个线程在某个集合点处进行相互等待
- Phaser:可以把并发任务分成多个阶段运行,在进行下一阶段之前,当前阶段的所有线程都必须执行完成
- Exchanger:提供两个线程之间的数据交换点
1、如果线程要访问一个共享资源,必须先获得信号量。如果信号量的计数器大于0,信号量减一,然后允许访问这个资源。
2、如果信号量的计数器等于0信号量就会把线程置为休眠直到信号量大于0.
3、当线程使用完某个共享资源时,信号量必须被释放,释放操作使信号量内部计数器加一
4、二进制信号量只能保护单一资源
三、注意
实现临界区的三个步骤:
1、acquire()获得信号量
2、对共享资源进行必要操作
3、通过release()释放信号量
四、其他方法
acquireUninterruptibly():就是acquire()方法,但是不抛出异常,当线程被阻塞这段时间,可能会中断。acquire()会抛出InterruptedExecption
public void acquireUninterruptibly() { sync.acquireShared(1); }public void acquire() throws InterruptedException { sync.acquireSharedInterruptibly(1); }tryAcquire():试图获取信号量
五、测试二进制信号量
package com.concurrent.threadAvgClass;/** * 打印工作类 * * @author Nicholas * */public class Job implements Runnable {private PrintQueue printQueue;public Job(PrintQueue printQueue) {this.printQueue = printQueue;}@Overridepublic void run() {System.out.println("Going to print a document "+ Thread.currentThread().getName());printQueue.PrintJob(new Object());System.out.println("The document has been printed "+ Thread.currentThread().getName());}}package com.concurrent.threadAvgClass;import java.util.concurrent.Semaphore;public class PrintQueue {// 声明一个信号量对象private final Semaphore semaphore;public PrintQueue() {semaphore = new Semaphore(1);}public void PrintJob(Object documentObject) {try {semaphore.acquire();Long duration = (long) (Math.random() * 10);System.out.println(Thread.currentThread().getName()+ " : PrintQueue : Printing a Job during "+ (duration / 1000) + " seconds");Thread.sleep(duration);} catch (InterruptedException e) {e.printStackTrace();}finally {semaphore.release();}}}
六、信号量如何实现保护资源的多个副本或者多个线程同时执行的临界区?
package com.concurrent.threadAvgClass;/** * 打印工作类 * * @author Nicholas * */public class Job2 implements Runnable {private PrintQueue2 printQueue;public Job2(PrintQueue2 printQueue) {this.printQueue = printQueue;}@Overridepublic void run() {System.out.println("Going to print a document "+ Thread.currentThread().getName());printQueue.PrintJob(new Object());System.out.println("The document has been printed "+ Thread.currentThread().getName());}}package com.concurrent.threadAvgClass;import java.util.concurrent.Semaphore;import java.util.concurrent.TimeUnit;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class PrintQueue2 {// 声明一个信号量对象private final Semaphore semaphore;private boolean[] freePrinters; // 存放打印机的状态,两种状态:空闲或者正在打印private Lock lockFreePrinters;// 锁对象,保护对freePrinters的访问public PrintQueue2() {semaphore = new Semaphore(3);freePrinters = new boolean[3];for (int i = 0; i < freePrinters.length; i++) {freePrinters[i] = true;}lockFreePrinters = new ReentrantLock();}public void PrintJob(Object documentObject) {try {semaphore.acquire();//获取当前空闲的打印机int assignedPrinter = getPrinter();Long duration = (long) (Math.random() * 10);System.out.printf("%s : PrintQueue : Printing a job at Printer %d during %d seconds",Thread.currentThread().getName(), assignedPrinter,duration);TimeUnit.SECONDS.sleep(duration);//打印完毕,将当前打印机置为空闲freePrinters[assignedPrinter] = true;} catch (InterruptedException e) {e.printStackTrace();} finally {semaphore.release();}}/** * 返回一个当前空闲的打印机编号 * @return */private int getPrinter() {int ret = -1;//表示打印机的编号try {lockFreePrinters.lock();for (int i = 0; i < freePrinters.length; i++) {//找到空闲的打印机if (freePrinters[i]) {ret = i;freePrinters[i] = false;//表示当前打印机已被使用break;}}} catch (Exception e) {e.printStackTrace();} finally {lockFreePrinters.unlock();}return ret;}}package com.concurrent.threadAvgClass;public class Main {public static void main(String[] args) {/*PrintQueue printQueue = new PrintQueue();Thread[] threads = new Thread[10];for (int i = 0; i < 10; i++) {threads[i] = new Thread(new Job(printQueue), "Thread-" + i);}for (int i = 0; i < 10; i++) {threads[i].start();}*/PrintQueue2 printQueue2 = new PrintQueue2();Thread[] threads = new Thread[10];for (int i = 0; i < 10; i++) {threads[i] = new Thread(new Job2(printQueue2), "Thread-" + i);}for (int i = 0; i < 10; i++) {threads[i].start();}}}
0 0
- Java并发编程-11-线程同步辅助类-semaphore
- 《java并发编程实战》:线程同步辅助类之信号量(semaphore)
- Java并发编程-同步辅助类之Semaphore
- 《java并发编程实战》:线程同步辅助类之CountDownLatch
- java并发编程之线程同步辅助类(一)
- java并发编程之线程同步辅助类(二)
- java并发编程实战手册第三章同步辅助类--Semaphore
- 并发编程实战手册-线程同步辅助类之CyclicBarrier
- Java7并发编程--3、线程同步辅助类
- Java并发编程-同步辅助类之CountDownLatch
- Java并发编程-同步辅助类之CyclicBarrier
- Java并发编程-同步辅助类之Phaser
- Java并发编程-同步辅助类之Exchanger
- Java并发编程-同步辅助类之Phaser
- Java并发编程-同步辅助类之CountDownLatch
- java并发编程(11)--Semaphore
- Semaphore -- 同步辅助类3
- java 多线程同步辅助类(CountDownLatch、CyclicBarrier、Semaphore、Exchanger)
- 使用NSOperation以及NSOperationQueue
- jdbc工作原理
- vs2010 问题 >LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
- AndroidのListView之滑动列表项(点击事件和滑动事件共存)
- Java程序员不该有的6种陋习
- Java并发编程-11-线程同步辅助类-semaphore
- Android高级模糊技术
- CLOSE SO仍然挂在 MD04 CO09的需求可用SDRQCR21清理
- 交换两个字符串内容
- eclipse Project的属性Deployment Assembly(支配程序集)
- android Bitmap.Config
- ActiveRecord migration的Java实现 -- Timachine
- Android Camera 3D效果
- Android 平台的檔案讀寫方式