本文主要是介绍java 信号量Semaphore的使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
java 信号量Semaphore的使用
信号量是一种计数器,用来保护一个或者多个共享资源的访问。
信号量的使用:
(1)如果一个线程要访问一个共享资源,他必须先获得信号量。如果信号量的内部计数器大于0,信号量将减1,然后允许访问这个共享资源。计数器大于0意味着又可以使用的资源,因此线程讲被允许使用其中一个资源。
(2)如果信号量等于0,信号将将会把线程植入休眠直到计数器大于0.计数器等于0的时候意味着所有的共享资源已经被其他线程使用了,所以需要访问这个共享资源的线程必须等待。
(3)当线程使用完这个共享资源时,信号量必须被释放,以便其他线程能够访问共享资源,释放操作将使用信号量的内部计数器增加1。
本节教你,在java中如何实现java的Semaphore信号量类,主要用到Semaphore类的acquire()方法和release()方法,分别是获取资源和释放资源的意思,最后我会解释Semaphore类的源码作分析。
我们的演示例子功能是:我们将实现一个打印队列,并发任务将使用它来完成打印。这个打印队列受信号量保护,因而同一时刻只有一个线程可以执行打印。
代码如下:
package test1;import java.util.concurrent.Semaphore;public class SemaphoreDemo {public static void main(String[] args) {PrintQueue printQueue = new PrintQueue();Thread thread[] = new Thread[10];for (int i = 0; i < 10; i++) {thread[i] = new Thread(new Job(printQueue),"Thread"+i);}for (int i = 0; i < 10; i++) {thread[i].start();}}}class PrintQueue {private final Semaphore semaphore;public PrintQueue() {semaphore = new Semaphore(1);//这是一个二进制信号量哦,计数器值只能是0或者1;}public void printJob (Object document) {try {semaphore.acquire();//获取共享资源,如果计数器为0会等待long duration = (long) (Math.random()*10);System.out.printf("%s: PrintQueue: Printing a job during %d seconds \n",Thread.currentThread().getName(),duration);Thread.sleep(duration);} catch (InterruptedException e) {e.printStackTrace();} finally {semaphore.release();//放在finally语句块表示不管发不发生异常都会执行,都会释放资源。}}
}class Job implements Runnable {private PrintQueue printQueue;public Job(PrintQueue printQueue) {this.printQueue = printQueue;}@Override public void run() {System.out.printf("%s: Going to print a job\n",Thread.currentThread().getName());printQueue.printJob(new Object());System.out.printf("%s: The document has been printed\n",Thread.currentThread().getName());}
}
输出结果:
Thread1: Going to print a job
Thread9: Going to print a job
Thread8: Going to print a job
Thread7: Going to print a job
Thread5: Going to print a job
Thread3: Going to print a job
Thread6: Going to print a job
Thread4: Going to print a job
Thread2: Going to print a job
Thread0: Going to print a job
Thread1: PrintQueue: Printing a job during 4 seconds
Thread1: The document has been printed
Thread9: PrintQueue: Printing a job during 6 seconds
Thread9: The document has been printed
Thread8: PrintQueue: Printing a job during 4 seconds
Thread8: The document has been printed
Thread7: PrintQueue: Printing a job during 6 seconds
Thread7: The document has been printed
Thread5: PrintQueue: Printing a job during 3 seconds
Thread5: The document has been printed
Thread3: PrintQueue: Printing a job during 2 seconds
Thread3: The document has been printed
Thread6: PrintQueue: Printing a job during 9 seconds
Thread6: The document has been printed
Thread4: PrintQueue: Printing a job during 3 seconds
Thread4: The document has been printed
Thread2: PrintQueue: Printing a job during 1 seconds
Thread2: The document has been printed
Thread0: PrintQueue: Printing a job during 3 seconds
Thread0: The document has been printed
仔细看看结果哦,一开始大家都在等待,只能一个一个打印哦;
这篇关于java 信号量Semaphore的使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!