首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >java信号量习惯用法

java信号量习惯用法
EN

Stack Overflow用户
提问于 2013-01-09 14:57:33
回答 2查看 576关注 0票数 2

我有一个线程,它只在独占访问2个信号量时才执行操作。

代码语言:javascript
复制
public void run(){
            boolean a1=false;
            boolean a2=false;
            boolean a3=false;
            while(true){
                try{
                    if(res[1].tryAcquire()==true){
                        a1=true;
                        if((res[2].tryAcquire()==true){
                            a2=true;
                            if(res[3].tryAcquire()==true)){
                                a3=true;
                                System.out.println("Rolled the tobacco");
                            }
                        }   
                    }
                }
                finally{
                    if(a1){
                        a1=false;
                        res[1].release();
                    }
                    if(a2){
                        a2=false;
                        res[2].release();
                    }
                    if(a3){
                        a3=false;
                        res[3].release();
                    }
                }
            }
        }
    }

有没有一种更好的方法来写这段代码,以确保我们不会打乱获取的信号量计数?有没有办法检查当前线程是否获取了信号量?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-01-09 15:21:17

在Java7中,可以尝试使用Closeable。当然,肯定有更好的解决方案。

代码语言:javascript
复制
public class Region implements Closeable {

    private final Semaphore semaphore;

    public Region(Semaphore semaphore) {
        this.semaphore = semaphore;
        if (!semaphore.tryAcquire()) {
            throw NotAcquiredException(semaphore);
        }
    }

    @Override
    public void close() {
         semaphore.release();
    }
}

public class NotAcquiredException extends Exception { ... }

用法:

代码语言:javascript
复制
    public void run() {
        boolean a1 = false;
        boolean a2 = false;
        boolean a3 = false;
        while (true) {
            try (Closeable r1 = new Region(res[1])) {
                 a1 = true;
                 try (Closeable r2 = new Region(res[2])) {
                     a2 = true;
                     try (Closeable r3 = new Region(res[3])) {
                          a3 = true;
                          System.out.println("Rolled the tobacco");
                     } catch (IOException e) {
                     }
                 } catch (IOException e) {
                 }
            } catch (IOException e) {
            }
       }
票数 2
EN

Stack Overflow用户

发布于 2013-01-09 15:41:15

您可以将每个获取分离到一个try...finally中,而不是更短,但去掉了一些变量,并使每个锁应该发生的事情变得相当明显。(我将数组改为从零开始)

代码语言:javascript
复制
public void run(){
    while(true){
        if(res[0].tryAcquire()){
            try {
                if(res[1].tryAcquire()) {
                    try {
                    if(res[2].tryAcquire()){
                        try {
                            System.out.println("Rolled the tobacco");
                        } finally {
                            res[3].release();
                        }
                    }
                    } finally {
                        res[2].release();
                    }                               
                }
            } finally{
                res[1].release();
            }
        }
    }
}

如果您需要获取大量的锁,或者在多个地方执行此操作,那么一个helper类可能会更好。至少隐藏了获取和释放信号量的样板代码。

代码语言:javascript
复制
public void run() {
    SemaphoreHelper semaphoreHelper = new SemaphoreHelper(res);
    while (true) {
        try {
            if (semaphoreHelper.aquireAll()) {
                System.out.println("Rolled the tobacco");
            }
        } finally {
            semaphoreHelper.releaseAquired();
        }
    }
}

private static class SemaphoreHelper {

    private final Semaphore[] semaphores;
    private int semaphoreIndex;

    public SemaphoreHelper(Semaphore[] semaphores) {
        this.semaphores = semaphores;
    }

    public void releaseAquired() {
        while (semaphoreIndex > 0) {
            semaphoreIndex--;
            semaphores[semaphoreIndex].release();
        }
    }

    public boolean aquireAll() {
        while (semaphoreIndex < semaphores.length) {
            if (!semaphores[semaphoreIndex].tryAcquire()) {
                return false;
            }
            semaphoreIndex++;
        }
        return true;
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14229858

复制
相关文章

相似问题

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