信号量 Semaphore

 Semaphore当前在多线程环境下被扩放使用,操作系统的信号量是个很重要的概念,在进程控制方面都有应用。Java 并发库 的Semaphore 可以很轻松完成信号量控制,Semaphore可以控制某个资源可被同时访问的个数,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。比如在Windows下可以设置共享文件的最大客户端访问个数。 

 

package learnthread.ftask;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Semaphore;

public class BoundHashSet<T> {
    private final Set<T> set;
    private final Semaphore sem;// 信号量

    public BoundHashSet(int bound) {
        set = Collections.synchronizedSet(new HashSet<T>());
        sem = new Semaphore(bound);
    }

    public boolean add(T o) throws InterruptedException {
        sem.acquire();
        boolean wasAdd = false;
        try {
            set.add(o);// 添加时可能由于资源耗尽,添加会出异常,需要判断是否真的添加,如果添加则释放
            wasAdd = true;
        } finally {
            if (!wasAdd) {
                sem.release();
            }
        }
        return wasAdd;
    }

    public boolean remove(T o) {
        boolean remove = set.remove(o);
        if (remove) {
            sem.release();
        }
        return remove;
    }

    public String toString() {
        return set.toString();

    }

    public static void main(String[] args) {
        final BoundHashSet<Integer> set = new BoundHashSet<Integer>(3);
        final CountDownLatch latch = new CountDownLatch(2);
        Thread t1 = new Thread(new Runnable() {

            @Override
            public void run() {
                for (int i = 0; i < 4; i++) {
                    try {
                        System.out.println("正在添加元素" + i);
                        System.out.println(set.add(i));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                latch.countDown();

            }
        });
        Thread t2 = new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("正在移除元素");
                System.out.println(set.remove(1));
                latch.countDown();

            }
        });
        t1.start();
        t2.start();
        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(set.toString());

    }
}

正在添加元素0
true
正在添加元素1
true
正在添加元素2
true
正在添加元素3
正在移除元素
true
true
[0, 2, 3]

posted @ 2016-02-29 11:28  程序猿进化之路  阅读(145)  评论(0)    收藏  举报