首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java中不可重入的非阻塞信号量

Java中不可重入的非阻塞信号量
EN

Stack Overflow用户
提问于 2012-09-26 08:16:53
回答 2查看 2.4K关注 0票数 2

我需要一个具有以下功能的信号量:

  1. 它应该是非阻塞的,也就是说,如果线程不能获得许可,它应该继续前进而无需等待。
  2. 它应该是不可重入的,也就是说,如果同一个线程两次进入受保护的代码,那么它应该取消两个许可,而不是一个。

我编写了以下代码:

代码语言:javascript
复制
public class SimpleSemaphore
{

    private int permits;

    private AtomicLong counter = new AtomicLong();

    SimpleSemaphore(int permits)
    {
        this.permits = permits;
    }

    boolean acquire()
    {

        if (counter.incrementAndGet() < permits)
        {
            return true;
        }
        else
        {
            counter.decrementAndGet();
            return false;
        }

    }

    void release()
    {
        counter.decrementAndGet();

    }
}

另一种选择是这个信号量:

代码语言:javascript
复制
public class EasySemaphore
{

    private int permits;

    private AtomicLong counter = new AtomicLong();

    EasySemaphore(int permits)
    {
        this.permits = permits;
    }

    boolean acquire()
    {
        long index = counter.get();

        if (index < permits)
        {
            if (counter.compareAndSet(index, index + 1))
            {
                return true;
            }
        }

        return false;
    }

    void release()
    {
        counter.decrementAndGet();
    }
}

这两种实现-线程安全和正确吗?哪一个更好?你将如何完成这项任务?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-09-26 08:22:03

java.util.concurrent.Semaphore不是已经这么做了吗?

它有一个用于非阻塞获取的tryAcquire,并且它保持一个简单的剩余许可计数(同一个线程可以取出多个许可)。

票数 7
EN

Stack Overflow用户

发布于 2012-09-26 08:23:18

我想说的是,第二个更好,因为计数器永远不会更大,泰坦0(和它略高的效率)

我将使用一个循环,否则,当仍然存在许可时,可以使该方法失败。

代码语言:javascript
复制
public class EasySemaphore {
    private final AtomicInteger counter;

    EasySemaphore(int permits) {
        counter = new AtomicInteger(permits);
    }

    boolean acquire() {
        // highly unlikely to loop more than once.
        while(true) {
            int count = counter.get();
            if (count <= 0) return false;
            if (counter.compareAndSet(count, count -1)) 
                return true;
        }
    }

    void release() {
        counter.incrementAndGet();
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12597407

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档