`
longzhun
  • 浏览: 372106 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Semaphore,动态增减信号量

 
阅读更多

【信号量】:

  • 用于控制对某资源访问的同一时间的并发量。

 

【如何获取】:

  • semaphore.tryAcquire(),尝试获取,不阻塞
  • semaphore.acquire(),没信号量可用时,将进行阻塞等

 

【如何释放】:

  • semaphore.release();
  • 线程抛出各种异常,都别忘了在finally中释放信号量;
  • 如果释放的比获取的信号量还多,例如获取了2个,释放了5次,那么当前信号量就动态的增加为5了,要注意。

 

【动态增加】:

  • 多释放几次,就可以达到信号量动态增加的效果了

 

【动态减小】:

  • 信号量本来有这个api的,不过是protected方法,所以我们需要显式继续Semaphore,并重新实现该api,见ResizeableSemaphore类中的reducePermits(int reduction);
  • 举例如下:(该表格有个假设前提,不存在多余的release而产生出新的信号量,即release次数<=acquire次数)
当前信号量A
(A=A1+A2)
占用信号量A1 可用信号量A2 重新设置信号量B
(B=B1+B2)
当前可用的信号量B1 当前待释放的量B2
5 3 2 3 0 0
5 3 2 1 0 -2
5 3 2 9 6 0



 

package com.jd.las.basic.service;

import java.util.concurrent.Semaphore;

/**
 * 
 * Title: 动态信号量<br>
 * 
 * Description: <br>
 * 
 * Company: <a href=www.jd.com>京东</a><br>
 * 
 * @author <a href=mailto:longzhun@jd.com>龙准</a>
 * 
 * @date 2015年5月26日 下午7:29:42
 */
public class JdSemaphore {

	 /**
     * semaphore starts at 0 capacity; must be set by setMaxPermits before use
     */
    private final ResizeableSemaphore semaphore = new ResizeableSemaphore();
 
    /**
     * how many permits are allowed as governed by this semaphore.
     * Access must be synchronized on this object.
     */
    private int maxPermits = 0;
 
    /**
     * New instances should be configured with setMaxPermits().
     */
    public JdSemaphore() {
        // no op
    }
 
    /*
     * Must be synchronized because the underlying int is not thread safe
     */
    /**
     * Set the max number of permits. Must be greater than zero.
     *
     * Note that if there are more than the new max number of permits currently
     * outstanding, any currently blocking threads or any new threads that start
     * to block after the call will wait until enough permits have been released to
     * have the number of outstanding permits fall below the new maximum. In
     * other words, it does what you probably think it should.
     *
     * @param newMax
     */
    public synchronized void setMaxPermits(int newMax) {
        if (newMax < 1) {
            throw new IllegalArgumentException("Semaphore size must be at least 1,"
                + " was " + newMax);
        }
 
        int delta = newMax - this.maxPermits;
 
        if (delta == 0) {
            return;
        } else if (delta > 0) {
            // new max is higher, so release that many permits
            this.semaphore.release(delta);
        } else {
            delta *= -1;
            // delta < 0.
            // reducePermits needs a positive #, though.
            this.semaphore.reducePermits(delta);
        }
 
        this.maxPermits = newMax;
    }
 
    /**
     * Release a permit back to the semaphore. Make sure not to double-release.
     *
     */
    public void release() {
        this.semaphore.release();
    }
 
    /**
     * Get a permit, blocking if necessary.
     *
     * @throws InterruptedException
     *             if interrupted while waiting for a permit
     */
    public void acquire() throws InterruptedException {
        this.semaphore.acquire();
    }
 
    /**
     * A trivial subclass of <code>Semaphore</code> that exposes the reducePermits
     * call to the parent class. Doug Lea says it's ok...
     * http://osdir.com/ml/java.jsr.166-concurrency/2003-10/msg00042.html
     */
    private static final class ResizeableSemaphore extends Semaphore {
        /**
         *
         */
        private static final long serialVersionUID = 1L;
 
        /**
         * Create a new semaphore with 0 permits.
         */
        ResizeableSemaphore() {
            super(0);
        }
 
        @Override
        protected void reducePermits(int reduction) {
            super.reducePermits(reduction);
        }
    }

}

 

这里可参考:http://blog.teamlazerbeez.com/2009/04/20/javas-semaphore-resizing/

 

  • 大小: 33.1 KB
分享到:
评论

相关推荐

    Linux 0.11下信号量的简单实现——用生产者消费者做检验

    在计算机操作系统中,信号量(Semaphore)是一种非常重要的同步机制,用于解决多个进程之间的资源竞争问题。本项目针对的是Linux 0.11内核,它是一个早期版本的开源操作系统,对于理解操作系统底层原理有着重要价值...

    linux任务和信号量的使用

    它是一个整型变量,可以被增减,并且可以被信号量操作(如`sem_wait()`和`sem_post()`)挂起或唤醒任务。`sys_sem.c`和`sys_sem.h`文件中,可能会包含信号量的初始化、等待、释放等相关函数,如`sem_init()`用于初始...

    lab4-171830635俞星凯1

    每个系统调用都涉及对信号量状态的管理,包括其值的增减以及对阻塞进程队列的处理。例如,SEM_POST操作会增加信号量的值,若值小于等于0,就唤醒阻塞队列中最先被阻塞的进程。 生产者消费者问题是多进程同步的经典...

    生产者消费者C++.pdf

    `Producer`函数中,`Produce`函数模拟生产新产品,然后使用`Append`函数将产品放入缓冲区,同时处理信号量的增减。`Consumer`函数则从缓冲区取出产品并消费,同样需要处理信号量的同步。 通过这样的设计,生产者-...

    ucos-ii_test3.rar_ucos_任务调度_淇″彿 ucos

    在这个测试案例中,我们利用了信号量(Semaphore)进行任务间的同步和资源管理。信号量是一种多任务间共享资源的机制,可以理解为一种计数器,其值的增减用于控制任务的执行顺序。例如,我们可以创建一个计数值为1的...

    操作系统pv操作金牌讲解

    PV操作源于信号量(Semaphore)的概念,分为P操作(Wait或Acquire)和V操作(Signal或Release)。这些操作用于控制对共享资源的访问,确保并发执行的进程能够正确地协调它们的执行顺序,避免数据竞争和死锁等问题。 ...

    推选文档操作系统教程-南通大学PPT.ppt

    为了解决这个问题,通常使用信号量(Semaphore)和PV操作。信号量是一种同步原语,用于控制对共享资源的访问。在生产者-消费者问题中,我们可以设置两个信号量:一个是用于保护缓冲区的信号量full,其初始值为0,...

    PV操作示例代码

    在操作系统领域,PV操作是进程同步的基本工具,源自荷兰计算机科学家埃德加·科德(Edsger Dijkstra)提出的信号量(Semaphore)概念。PV操作由两个原子操作组成:P(Wait)操作和V(Signal)操作,主要用于解决多...

    图解linux进程间通信机制

    为了实现进程间的协作,Linux提供了多种IPC机制,包括管道(Pipe)、消息队列(Message Queue)、信号量(Semaphore)、共享内存(Shared Memory)、套接字(Socket)以及有名管道(FIFO)等。 1. **管道**:管道是...

    操作系统简答题.pdf

    9. **信号量 (Semaphore)**:信号量是一种同步机制,用于保护共享资源。它可以是整型变量,通过wait()和signal()操作进行增减,确保对资源的互斥访问。 10. **LUT (Look-up Table)**:查找表是预存信息的数据结构,...

    T-kernel-OS.rar_Kernel_T-kernel OS_os_t kernel_tinyos

    而"sem"文件名暗示这可能是关于信号量(Semaphore)的源代码或文档,信号量在多任务系统中用于同步和互斥访问共享资源,是T-KERNEL中的关键机制之一。 深入研究这些源码,开发者可以了解到T-KERNEL如何实现任务调度...

    ipc.zip_IPC

    4. **信号量**:信号量用于解决资源的互斥访问和同步问题,通过计数值的增减来控制多个进程对共享资源的访问。 5. **共享内存**:共享内存允许进程直接读写同一块内存区域,速度快但需要额外的同步机制,如互斥锁,...

    java火车售票

    Java的`java.util.concurrent`包提供了许多并发工具类,如`Semaphore`(信号量)、`CountDownLatch`(计数器门锁)等,这些工具可以帮助我们更好地管理并发资源。 8. **线程通信** 使用`wait()`、`notify()`和`...

    腾讯后台开发实习生技能要求

    了解如何使用互斥体(mutex)、信号量(semaphore)和条件变量(condition variable)进行线程间的同步,比如互斥体的初始化、锁定、解锁操作,信号量的增减以及条件变量的等待与通知。 2. 自旋锁(spinlock)和...

    走近WinCE BSP 开发

    - **同步**:Windows CE 提供了多种同步机制,包括互斥体(Mutex)、信号量(Semaphore)、事件(Event)等,其中 Mutex、Semaphore 和 Event 可以实现跨进程同步,而 CriticalSection 和 InterlockedFunctions 则...

    银行系统的原版课程设计

    在多线程环境下,可能需要使用互斥锁(mutex)或者信号量(semaphore)来实现同步。 4. **客户管理**:每个账户都关联一个客户,因此需要有客户类来存储客户信息。可能还包括添加新客户、删除客户、查找客户等功能...

Global site tag (gtag.js) - Google Analytics