Semaphore示例

java.util.concurrent.Semaphore提供了控制并发的工具类,关键方法是acquire()release(),它提供一种基于许可的同步机制,初始化一定的许可数量,同步参与者先获取许可,再执行操作,然后释放许可。假如将许可数设置为1,就是一种简单的互斥锁的实现,即同一时间只有一个线程获取到许可。见下面的代码示例:

public class TestSemaphore {
    public static void main(String[] args) {
        final Semaphore s = new Semaphore(1);
        for (int i=0; i<10; i++) {
            new Thread("worker" + i) {
                public void run() {
                    try {
                        s.acquire();
                        Thread curT = Thread.currentThread();
                        System.out.println(curT + ": I am tired, sleeping~");
                        Thread.sleep(Math.round(Math.random() * 3000));
                        System.out.println(curT + ": sleep over~");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    
                    s.release();
                }
            }.start();
        }
    }
}

Semaphore可以控制同一时间的并发数,于是自然可以想到另一个常用的使用场景--资源池,如下面的代码示例,实现任意资源的池化。

class MyPool {
    Object[] items;
    int poolSize;
    Semaphore available;
    boolean[] used;
    
    public MyPool(Object[] poolRes) {
        if (null == poolRes) {
            poolRes = new Object[0];
        }
        
        this.items = poolRes;
        this.poolSize = poolRes.length;
        this.available = new Semaphore(poolSize, true);
        this.used = new boolean[poolSize];
    }
    
    public Object acquire() throws InterruptedException {
        available.acquire();
        return getNextAvailableItem();
    }
    
    public void release(Object x) {
        if (markAsUnused(x)) {
            available.release();
        }
    }
    
    private synchronized Object getNextAvailableItem() {
        for (int i=0; i<poolSize; ++i) {
            if (!used[i]) {
                used[i] = true;
                return items[i];
            }
        }
        return null; // not reached
    }
    
    private synchronized boolean markAsUnused(Object item) {
        for (int i=0; i<poolSize; ++i) {
            if (item == items[i]) {
                if (used[i]) {
                    used[i] = false;
                    return true;
                }
                return false;
            }
        }
        return false;
    }
}

和前面几篇文章一起,分别介绍了CountDownLatch/CyclicBarrier/Exchanger/Semaphore/Phaser,下面对各自的常用使用场景做个小小的总结:

1、Semaphore

控制并发数/互斥锁、资源池

2、Exchanger

协作成对线程交互数据

3、CountDownLatch

等待N个条件到达,等待一起出发。

4、CyclicBarrier

阶段协同器(各阶段参与者数量固定)

5、Phaser

阶段协同器(各阶段参与者数量可变)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值