首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Java信号量(tryAcquire)的问题

Java信号量(tryAcquire)的问题
EN

Stack Overflow用户
提问于 2022-07-04 15:54:32
回答 1查看 66关注 0票数 -1

我试图用以下代码生成AAB AAB序列:

代码语言:javascript
运行
复制
private static Semaphore semA = new Semaphore(2);
private static Semaphore semB = new Semaphore(0);

public static void main(String[] args) {
    while(true) {
        new P1A().start();
        new P2B().start();
        try {
            Thread.sleep(1000);
        }
        catch(InterruptedException e) {
            e.printStackTrace();
        }
    }

}

static class P1A extends Thread{
    
    public void run() {
        try {
            semA.acquire();
            System.out.print("A");
            if(!semA.tryAcquire()) {
                semB.release();
            }
        }
        catch(InterruptedException e) {
            e.printStackTrace();
        }
    }
}

static class P2B extends Thread{
    
    public void run() {
        try {
            semB.acquire();
            System.out.print("B ");
            semA.release(2);
        }
        catch(InterruptedException e) {
            e.printStackTrace();
        }
    }
}

在这段代码中,最终结果是"A“。

据我所知,tryAcquire ()应该立即返回true或false,而不是延迟响应。我们如何解决这个问题呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-04 20:46:23

这主要是对您的问题的解释和分析方法--但我确实看到了您正在尝试的内容,并添加了一个简单的解决方案。

在遍历逻辑时最好使用表。请注意,P1AP2B的执行顺序可能不同,因此这是一个序列--但我确信所有序列都会导致所描述的相同结果:

代码语言:javascript
运行
复制
|     P1A     | semA |     P2B     | semB | Output |
| ----------- | ---- | ----------- | ---- | ------ |
| [1] started |      |             |      |        |
|             |   2  |             |   0  |        |
| [1] acq  A  |   1  |             |   0  |        |
|             |      |             |      |    A   |
| [1] acqt A  |   0  |             |   0  |        |
|             |      | [1] started |   0  |        |
|             |   0  | [1] blocked |   0  |        |
| [1] end     |   0  |             |   0  |        |
| [2] started |   0  |             |   0  |        |
| [2] blocked |   0  |             |      |        |
|             |   0  | [2] started |   0  |        |
|             |   0  | [2] blocked |   0  |        |

无限的。

在每次迭代中启动新线程似乎只会使结果复杂化--而不是让每个线程自己永远循环。

因为semA是用2个许可证初始化的,所以tryAcquire将是成功的(true),因此!tryAcquire是假的。

更新P1A

现在我看到了你们正在尝试的东西,我认为下面更直接地说明你们的方法。只需让P1A这样做(保留P2B原样):

代码语言:javascript
运行
复制
public void run() {
        if (semA.tryAcquire()) {
           System.out.print("A");
        } else {
            semB.release();
        }
}

关于主循环,我不能说它是错误的,除非它不会等待线程完成(连接),这只会导致混乱的结果。因此,要么join两个线程(而不是睡眠),要么将永久循环移动到线程中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72859353

复制
相关文章

相似问题

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