并发编程之信号量Semaphore

来源:互联网 发布:jquery格式化json日期 编辑:程序博客网 时间:2024/04/30 09:04

      在以前的操作系统学习中,为了实现进程的同步,需要设置信号量执行P、V操作来实现。在Java中,线程之间的同步也是使用信号量Semaphore类来实现的。线程访问临界资源(需互斥访问的那段代码)的时候,如果信号量(计数器)大于0,则允许进入临界资源,若信号量小于等于0,则线程阻塞等待另外的线程释放临界资源。Java 并发库的Semaphore 可以很轻松完成信号量控制,Semaphore 通常用于限制可以访问某些资源(物理或逻辑的)的线程数目。通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。比如在Windows下可以设置共享文件的最大客户端访问个数。

Semaphore概述
---通常把一个非负整数称为Semaphore,表示为S.
    S可以理解为可用的资源数量.这里不涉及进程问题,所以就假定S>=0.
---S实现的同步机制表示为PV原语操作
    P(S):若S=0,线程进入等待队列;否则,—S;
    V(S):++S,唤醒处于等待中的线程.

     信号量的特性如下:信号量是一个非负整数,所有通过它的线程都会将该整数减一,当该整数值为零时,所有试图通过它的线程都将处于等待状态。在信号量上我们定义两种操作: Acquire(等待) 和 Release(释放)。当一个线程调用Acquire(等待)操作时,它要么通过然后将信号量减一,要么一直等下去,直到信号量大于一或超时。Release(释放)实际上是在信号量上执行加操作,加操作实际上是释放了由信号量守护的资源。

    在java中,还可以设置该信号量是否采用公平模式,如果以公平方式执行,则线程将会按到达的顺序(FIFO)执行,如果是非公平,则可以后请求的有可能排在队列的头部。
    1、Semaphore(int permits, boolean fair):创建具有给定的许可数和给定的公平设置的Semaphore。在该构造函数中,permits指定了计数器的初始值,如果permits=1,则说明在某个时间间隔之内,只允许一个线程访问临界资源,默认情况下(fair默认为false,即不采用公平策略),等待线程以随机顺序获取临界资源(当permits>0时),若将fair设置为true,则采用公平策略,等待线程已他们要求的访问顺序获取临界资源。
    2、Semaphore类中,请求获取临界资源的方法如下所示:tryAcquire、acquire;
    3、Semaphore类中,请求获取临界资源的方法如下所示:release;

示例程序:

import java.util.concurrent.Semaphore;import java.util.concurrent.TimeUnit;public class Bank {private final static int COUNT = 100;private final static Semaphore semaphore = new Semaphore(3, true);public static void main(String[] args) {for (int i = 0; i < COUNT; i++) {final int count = i;new Thread(new Runnable() {@Overridepublic void run() {try {// 没有可用的资源就等待一段时间,如果在该时间内仍未获取到所需要的资源semaphore,就返回false// 这里只申请一个,如果申请多个需要调用其他的请求方法if (semaphore.tryAcquire(10, TimeUnit.MILLISECONDS)) {try {Teller.getService(count);} finally {// 释放所获取到的资源semaphoresemaphore.release();}}} catch (InterruptedException e) {e.printStackTrace();}}}).start();}}}class Teller {static public void getService(int i) {System.out.println("serving:" + i);try {Thread.sleep((long) (Math.random() * 100));} catch (InterruptedException e) {}}}

运行结果(一种)

serving:10serving:0serving:11serving:9serving:8

原创粉丝点击