Semaphore(计数信号量)

//对象池public class Pool<T> {
    private int size;
    private List<T> items = new ArrayList<T>();
    private volatile boolean[] checkedOut;
    private Semaphore available;
    public Pool(Class<T> classObject,int size) {
        this.size = size;
        this.checkedOut = new boolean[size];
        this.available = new Semaphore(size, true);
        for (int i = 0; i < size; i++) {
            try {
                items.add(classObject.newInstance());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }
    public T checkOut() throws InterruptedException{
        available.acquire();
        return getItem();
    }
    public void checkIn(T x){
        if(releaseItem(x)){
            available.release();
        }
    }

    private synchronized T getItem(){
        for (int i = 0; i < size; ++i) {
            if(!checkedOut[i]){
                checkedOut[i] = true;
                return items.get(i);
            }
        }
        return null;
    }
    private synchronized boolean releaseItem(T item){
        int index = items.indexOf(item);
        if(index == -1){
            return false;
        }
        if(checkedOut[index]){
            checkedOut[index] = false;
            return true;
        }
        return false;
    }
}
//签出任务class CheckoutTask<T> implements Runnable{
    private static int counter = 0;
    private final int id = counter++;
    private Pool<T> pool;
    public CheckoutTask(Pool<T> pool) {
        this.pool = pool;
    }

    @Override
    public void run() {
        try {
            T item = pool.checkOut();
            System.out.println(this + "checked out " + item);
            TimeUnit.SECONDS.sleep(1);
            System.out.println(this + "checked in " + item);
            pool.checkIn(item);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    @Override
    public String toString() {
        return "CheckoutTask " + id + " ";
    }
}

public class SemaphoreDemo {
    final static int SIZE = 25;
    public static void main(String[] args) throws InterruptedException {
        final Pool<Fat> pool = new Pool<Fat>(Fat.class, SIZE);
        ExecutorService exec = Executors.newCachedThreadPool();
        for (int i = 0; i < SIZE; i++) {
            exec.execute(new CheckoutTask<Fat>(pool));
        }
        System.out.println("All CheckoutTask created");
        List<Fat> list = new ArrayList<Fat>();
        System.out.println("kifjdskjfjdk");
        for (int i = 0; i < SIZE; i++) {
            Fat f = pool.checkOut();
            System.out.println(i + ":main() thread checked out ");
            f.operation();
            list.add(f);
        }
        Future<?> blocked = exec.submit(new Runnable() {
            @Override
            public void run() {
                try {
                    pool.checkOut();
                } catch (InterruptedException e) {
                    System.out.println("checkedOut() Interrupted");
                }
            }
        });
        TimeUnit.SECONDS.sleep(2);
        blocked.cancel(true);
        System.out.println("Checking in objects in " + list);
        for (Fat f : list) {
            pool.checkIn(f);
        }
        for (Fat f : list) {
            pool.checkIn(f);
        }
        exec.shutdown();
    }

}
public class Fat {
    private volatile double d;
    private static int counter = 0;
    private final int id = counter++;
    public Fat() {
        for (int i = 0; i <10000; i++) {
            d +=(Math.PI + Math.E) / i;
        }
    }
    public void operation(){
        System.out.println(this);
    }
    @Override
    public String toString() {
        return "Fat id: " + id;
    }
}
时间: 2024-12-25 14:21:33

Semaphore(计数信号量)的相关文章

java中的计数信号量(Counting Semaphore)

信号量(Semaphore)又称为信号量.旗语,它以一个整数变数,提供信号,以确保在并行计算环境中,不同进程在访问共享资源时,不会发生冲突.是一种不需要使用忙碌等待(busy waiting)的一种方法. 信号量的概念是由荷兰计算机科学家艾兹格·迪杰斯特拉(Edsger W. Dijkstra)发明的,广泛的应用于不同的操作系统中.在系统中,给予每一个进程一个信号量,代表每个进程目前的状态,未得到控制权的进程会在特定地方被强迫停下来,等待可以继续进行的信号到来.如果信号量是一个任意的整数,通常被

Semaphore(信号量)

场景:当多个任务或线程并行运行时,难以避免的对某些有限的资源进行并发的访问 可以考虑使用信号量来进行这方面的控制(System.Threading.Semaphore)是表示一个Windows内核的信号量对象(操作系统级别,可以跨进程或AppDomain).如果预计等待的时间较短,使用SemaphoreSlim(单进程)带来的开销更小.关于两者的区别如下: System.Threading.Semaphore 类表示一个命名(系统范围内)或本地信号量.它是环绕 Win32 信号量对象的精简包装器

【C#】【Thread】Semaphore/SemaphoreSlim信号量

System.Threading.Semaphore 类表示一个命名(系统范围)信号量或本地信号量. 它是一个对 Win32 信号量对象的精简包装. Win32 信号量是计数信号量,可用于控制对资源池的访问.      SemaphoreSlim 类表示一个轻量的快速信号量,可用于在一个预计等待时间会非常短的进程内进行等待. SemaphoreSlim 会尽可能多地依赖由公共语言运行时 (CLR) 提供的同步基元. 但是,它也会根据需要提供延迟初始化的.基于内核的等待句柄,以支持等待多个信号量.

Cocoa多线程编程之block与semaphore(信号量)

首先大家要了解 dispatch_queue 的运作机制及线程同步 我们可以将许多 blocks 用 dispatch_async 函数提交到 dispatch_queue ,如果类型是DISPATCH_QUEUE_SERIAL (串行),那么这些 block 是按照 FIFO (先入先出)的规则调度的,也就是说,先加入的先执行,后加入的一定后执行,但在如果类型是DISPATCH_QUEUE_CONCURRENT(并行),那么某一时刻就可能有多个 block 同时在执行. 这个时候,如果两个 b

Java之多线程 Semaphore(信号量)

一个计数信号量.从概念上讲,信号量维护了一个许可集.如有必要,在许可可用前会阻塞每一个 acquire(),然后再获取该许可.每个 release() 添加一个许可,从而可能释放一个正在阻塞的获取者.但是,不使用实际的许可对象,Semaphore 只对可用许可的号码进行计数,并采取相应的行动.拿到信号量的线程可以进入代码,否则就等待.通过acquire()和release()获取和释放访问许可. 相关方法: acquire public void acquire() throws Interru

java并发编程学习:用 Semaphore (信号量)控制并发资源

并发编程这方面以前关注得比较少,恶补一下,推荐一个好的网站:并发编程网 - ifeve.com,上面全是各种大牛原创或编译的并发编程文章. 今天先来学习Semaphore(信号量),字面上看,根本不知道这东西是干啥的,借用 并发工具类(三)控制并发线程数的Semaphore一文中的交通红绿信号灯的例子来理解一下: 一条4车道的主干道,假设100米长,每辆车假设占用的长度为10米(考虑到前后车距),也就是说这条道上满负载运行的话,最多只能容纳4*(100/10)=40辆车,如果有120辆车要通过的

FreeRTOS 任务计数信号量,任务二值信号量,任务事件标志组

本章节为大家讲解 FreeRTOS 计数信号量的另一种实现方式----基于任务通知(Task Notifications)的计数信号量,这里我们将这种方式实现的计数信号量称之为任务计数信号量. 任务计数信号量效率更高,需要的 RAM 空间更小.当然,缺点也是有的,它没有之前介绍的计数信号量实现的功能全面. 任务通知(Task Notifications)介绍FreeRTOS 每个已经创建的任务都有一个任务控制块(task control block),任务控制块就是一个结构体变量,用于记录任务的

FreeRTOS 计数信号量

本章节开始讲解 FreeRTOS 任务间的同步和资源共享机制,计数信号量. FreeRTOS 中计数信号量的源码实现是基于消息队列实现的. 信号量的概念及其作用信号量(semaphores)是 20 世纪 60 年代中期 Edgser Dijkstra 发明的. 使用信号量的最初目的是为了给共享资源建立一个标志,该标志表示该共享资源被占用情况.这样,当一个任务在访问共享资源之前,就可以先对这个标志进行查询,从而在了解资源被占用的情况之后,再来决定自己的行为.实际的应用中,信号量的作用又该如何体现

C#多线程のSemaphore(信号量,负责协调各个线程)

Semaphore负责协调线程,可以限制对某一资源访问的线程数量 这里对SemaphoreSlim类的用法做一个简单的例子: namespace WpfApplication6 { /// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window { static SemaphoreSlim semLim = new SemaphoreSlim(3); //