当前位置:首页 > 开发 > 编程语言 > 多线程 > 正文

Java 多线程之信号量-Semaphore

发表于: 2015-07-05   作者:zhangwei_david   来源:转载   浏览:
摘要:      技术信号量(Counting Semaphore)用来控制同时访问某个特定资源的操作数量,或者执行某个特定操作的数量。计数信号量还可以用来实现某种资源池或者对容器加边界。   Semaphore中管理着一组虚拟许可(permit),许可的初始数量可以通过在构造方法中指定。在执行操作时首先获取许可(permit),在使

     技术信号量(Counting Semaphore)用来控制同时访问某个特定资源的操作数量,或者执行某个特定操作的数量。计数信号量还可以用来实现某种资源池或者对容器加边界。

  Semaphore中管理着一组虚拟许可(permit),许可的初始数量可以通过在构造方法中指定。在执行操作时首先获取许可(permit),在使用完成后释放许可。如果没有许可,那么acquire则一直阻塞到有许可或者超时中断。

 

/**
 * 计数信号量(Counting Semaphore)用来控制同时访问某个特定资源的操作数量,或者执行某个指定操作的数量。
 * 计数信号量还可以用来实现某种资源池或者对容器进行加边界
 * Semaphore 中管理着一组虚拟的许可(permit),许可的初始化数量可以通过构造函数来指定。在执行操作时可以
 * 首先获取许可(只要还有剩余的许可),并在使用后释放许可(permit)。 如果没有许可(permit)那么aquire将阻塞
 * 直到有许可或者直到被中断、操作超时。release方法将释放一个许可,返回给信号量(semaphore)
 *
 * @author zhangwei_david
 * @version $Id: BoundedHashSet.java, v 0.1 2014年11月11日 下午1:49:24 zhangwei_david Exp $
 */
public class BoundedHashSet<T> {
    //
    private final Set<T>    set;
    // 信号量
    private final Semaphore sem;

    public BoundedHashSet(int bound) {
        //初始化一个同步Set
        this.set = Collections.synchronizedSet(new HashSet<T>());
        //初始化信号量大小
        sem = new Semaphore(bound);
    }

    public boolean add(T o) throws InterruptedException {
        // 获取许可
        sem.acquire();
        System.out.println("获取许可 " + sem.availablePermits());
        boolean wasAdded = false;
        try {
            wasAdded = set.add(o);
            return wasAdded;
        } finally {
            if (!wasAdded) {
                // 如果增加失败
                System.out.println("添加失败,释放许可");
                sem.release();
            }
        }
    }

    public boolean remove(Object o) {
        boolean wasRemoved = set.remove(o);
        if (wasRemoved) {
            // 删除后释放许可
            System.out.println("删除成功,释放许可");
            sem.release();
        }
        return wasRemoved;
    }

}

 

 

/**
 * 资源池
 * @author zhangwei_david
 * @version $Id: ResourcePool.java, v 0.1 2015年7月5日 上午9:53:18 zhangwei_david Exp $
 */
public class ResourcePool<T> {

    private int                size;

    private List<T>            items = new ArrayList<T>();

    private volatile boolean[] checkOut;

    private Semaphore          available;

    public ResourcePool(Class<T> clazz, int max) {
        size = max;
        checkOut = new boolean[size];
        available = new Semaphore(size);
        for (int i = 0; i < size; i++) {
            try {
                items.add(clazz.newInstance());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public T checkOut() throws InterruptedException {
        available.acquire();
        return getItem();
    }

    public void checkIn(T t) {
        if (releaseItem(t)) {
            available.release();
        }
    }

    /**
     *  释放对象,如果该对象在对象池中不存在则返回false
     *  如果该对象尚未被checkOut则返回fasle
     *  将checkOut标准置为false,返回true
     *
     * @param t
     * @return
     */
    private synchronized boolean releaseItem(T t) {
        int index = items.indexOf(t);
        if (index == -1) {
            return false;
        }
        if (checkOut[index]) {
            checkOut[index] = false;
            return true;
        }
        return false;
    }

    /**6
     * 如果还有对象没有checkOut则返回该对象,如果没有则返回null
     *
     * @return
     */
    private synchronized T getItem() {
        for (int i = 0; i < size; i++) {
            if (!checkOut[i]) {
                checkOut[i] = true;
                return items.get(i);
            }
        }
        return null;
    }
}

 

 

/**
 *
 * @author zhangwei_david
 * @version $Id: Link.java, v 0.1 2015年7月5日 上午10:11:03 zhangwei_david Exp $
 */
public class Link {

    private static int counter = 0;

    private final int  id      = counter++;

    public Link() {
        try {
            TimeUnit.MILLISECONDS.sleep(300);
        } catch (Exception e) {

        }
    }

    /**
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return "Link [ id=" + id + "]";
    }

}

 

/**
 *
 * @author zhangwei_david
 * @version $Id: SemaphoreDemo.java, v 0.1 2015年7月5日 上午10:20:16 zhangwei_david Exp $
 */
public class SemaphoreDemo {

    /**
     *
     * @param args
     */
    public static void main(String[] args) {

        final ResourcePool<Link> linkes = new ResourcePool<Link>(Link.class, 30);
        ExecutorService exec = Executors.newCachedThreadPool();
        for (int i = 0; i < 60; i++) {
            exec.execute(new CheckOutTask<Link>(linkes));
        }
        exec.shutdown();
    }

}

 

CheckOutTask [id=0] check out Link [ id=0]
CheckOutTask [id=1] check out Link [ id=1]
CheckOutTask [id=3] check out Link [ id=2]
CheckOutTask [id=2] check out Link [ id=3]
CheckOutTask [id=4] check out Link [ id=4]
CheckOutTask [id=6] check out Link [ id=5]
CheckOutTask [id=5] check out Link [ id=6]
CheckOutTask [id=7] check out Link [ id=7]
CheckOutTask [id=8] check out Link [ id=8]
CheckOutTask [id=9] check out Link [ id=9]
CheckOutTask [id=10] check out Link [ id=10]
CheckOutTask [id=11] check out Link [ id=11]
CheckOutTask [id=12] check out Link [ id=12]
CheckOutTask [id=13] check out Link [ id=13]
CheckOutTask [id=14] check out Link [ id=14]
CheckOutTask [id=15] check out Link [ id=15]
CheckOutTask [id=16] check out Link [ id=16]
CheckOutTask [id=17] check out Link [ id=17]
CheckOutTask [id=18] check out Link [ id=18]
CheckOutTask [id=19] check out Link [ id=19]
CheckOutTask [id=20] check out Link [ id=20]
CheckOutTask [id=21] check out Link [ id=21]
CheckOutTask [id=22] check out Link [ id=22]
CheckOutTask [id=23] check out Link [ id=23]
CheckOutTask [id=24] check out Link [ id=24]
CheckOutTask [id=25] check out Link [ id=25]
CheckOutTask [id=26] check out Link [ id=26]
CheckOutTask [id=27] check out Link [ id=27]
CheckOutTask [id=28] check out Link [ id=28]
CheckOutTask [id=29] check out Link [ id=29]
CheckOutTask [id=2] check in Link [ id=3]
CheckOutTask [id=1] check in Link [ id=1]
CheckOutTask [id=3] check in Link [ id=2]
CheckOutTask [id=4] check in Link [ id=4]
CheckOutTask [id=31] check out Link [ id=1]
CheckOutTask [id=30] check out Link [ id=2]
CheckOutTask [id=32] check out Link [ id=3]
CheckOutTask [id=33] check out Link [ id=4]
CheckOutTask [id=0] check in Link [ id=0]
CheckOutTask [id=34] check out Link [ id=0]
CheckOutTask [id=10] check in Link [ id=10]
CheckOutTask [id=15] check in Link [ id=15]
CheckOutTask [id=18] check in Link [ id=18]
CheckOutTask [id=12] check in Link [ id=12]
CheckOutTask [id=16] check in Link [ id=16]
CheckOutTask [id=14] check in Link [ id=14]
CheckOutTask [id=19] check in Link [ id=19]
CheckOutTask [id=5] check in Link [ id=6]
CheckOutTask [id=7] check in Link [ id=7]
CheckOutTask [id=9] check in Link [ id=9]
CheckOutTask [id=17] check in Link [ id=17]
CheckOutTask [id=37] check out Link [ id=7]
CheckOutTask [id=36] check out Link [ id=6]
CheckOutTask [id=35] check out Link [ id=10]
CheckOutTask [id=8] check in Link [ id=8]
CheckOutTask [id=40] check out Link [ id=14]
CheckOutTask [id=6] check in Link [ id=5]
CheckOutTask [id=42] check out Link [ id=15]
CheckOutTask [id=43] check out Link [ id=5]
CheckOutTask [id=44] check out Link [ id=16]
CheckOutTask [id=47] check out Link [ id=17]
CheckOutTask [id=45] check out Link [ id=18]
CheckOutTask [id=13] check in Link [ id=13]
CheckOutTask [id=11] check in Link [ id=11]
CheckOutTask [id=26] check in Link [ id=26]
CheckOutTask [id=55] check out Link [ id=13]
CheckOutTask [id=53] check out Link [ id=19]
CheckOutTask [id=56] check out Link [ id=26]
CheckOutTask [id=27] check in Link [ id=27]
CheckOutTask [id=41] check out Link [ id=8]
CheckOutTask [id=39] check out Link [ id=12]
CheckOutTask [id=38] check out Link [ id=9]
CheckOutTask [id=54] check out Link [ id=27]
CheckOutTask [id=52] check out Link [ id=11]
CheckOutTask [id=24] check in Link [ id=24]
CheckOutTask [id=25] check in Link [ id=25]
CheckOutTask [id=23] check in Link [ id=23]
CheckOutTask [id=57] check out Link [ id=23]
CheckOutTask [id=58] check out Link [ id=24]
CheckOutTask [id=50] check out Link [ id=25]
CheckOutTask [id=22] check in Link [ id=22]
CheckOutTask [id=21] check in Link [ id=21]
CheckOutTask [id=59] check out Link [ id=21]
CheckOutTask [id=20] check in Link [ id=20]
CheckOutTask [id=46] check out Link [ id=22]
CheckOutTask [id=51] check out Link [ id=20]
CheckOutTask [id=29] check in Link [ id=29]
CheckOutTask [id=49] check out Link [ id=29]
CheckOutTask [id=28] check in Link [ id=28]
CheckOutTask [id=48] check out Link [ id=28]
CheckOutTask [id=30] check in Link [ id=2]
CheckOutTask [id=33] check in Link [ id=4]
CheckOutTask [id=32] check in Link [ id=3]
CheckOutTask [id=31] check in Link [ id=1]
CheckOutTask [id=34] check in Link [ id=0]
CheckOutTask [id=45] check in Link [ id=18]
CheckOutTask [id=37] check in Link [ id=7]
CheckOutTask [id=36] check in Link [ id=6]
CheckOutTask [id=40] check in Link [ id=14]
CheckOutTask [id=42] check in Link [ id=15]
CheckOutTask [id=35] check in Link [ id=10]
CheckOutTask [id=43] check in Link [ id=5]
CheckOutTask [id=47] check in Link [ id=17]
CheckOutTask [id=44] check in Link [ id=16]
CheckOutTask [id=59] check in Link [ id=21]
CheckOutTask [id=46] check in Link [ id=22]
CheckOutTask [id=50] check in Link [ id=25]
CheckOutTask [id=58] check in Link [ id=24]
CheckOutTask [id=57] check in Link [ id=23]
CheckOutTask [id=54] check in Link [ id=27]
CheckOutTask [id=52] check in Link [ id=11]
CheckOutTask [id=38] check in Link [ id=9]
CheckOutTask [id=39] check in Link [ id=12]
CheckOutTask [id=56] check in Link [ id=26]
CheckOutTask [id=41] check in Link [ id=8]
CheckOutTask [id=53] check in Link [ id=19]
CheckOutTask [id=55] check in Link [ id=13]
CheckOutTask [id=48] check in Link [ id=28]
CheckOutTask [id=49] check in Link [ id=29]
CheckOutTask [id=51] check in Link [ id=20]

 

Java 多线程之信号量-Semaphore

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
简介 信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施, 它负责协调各个线程,
简介 信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施, 它负责协调各个线程,
简介 信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施, 它负责协调各个线程,
本文将介绍用来控制资源同时访问个数的Semaphore工具类,然后采用Semaphore给出一个泊车的实例,最
本文将介绍用来控制资源同时访问个数的Semaphore工具类,然后采用Semaphore给出一个泊车的实例,最
信号量说简单点就是为了线程同步,或者说是为了限制线程能运行的数量。 那它又是怎么限制线程的数量
前面介绍了关键段CS、事件Event、互斥量Mutex在经典线程同步问题中的使用。本篇介绍用信号量Semapho
原文地址:http://www.cnblogs.com/yuqilin/archive/2011/10/16/2214429.html semaphore 可用于进程
semaphore 可用于进程间同步也可用于同一个进程间的线程同步。 semaphore 非常类似于mutex , 共同
阅读本篇之前推荐阅读以下姊妹篇: 《秒杀多线程第四篇一个经典的多线程同步问题》 《秒杀多线程第
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号