你想象不到的菜 2021-08-17 15:39 采纳率: 0%
浏览 33

java多线程Semaphore的疑问



```java
public class SemaphoreTest {
    /**
     * 初始化信号量
     */
    static int count;
    static final Semaphore s = new Semaphore(1);
    /**
     * 用信号量保证互斥
     */
    static void addOne() throws InterruptedException {
        s.acquire();
        try {
            count++;
            System.out.println(SemaphoreTest.count);
        } finally {
            s.release();
        }
    }
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                try {
                    SemaphoreTest.addOne();
                    // 最开始我是放在这打印的,但是发现有重复的值,起初怀疑 addOne() 方法不是线程安全的,后来将打印发到 addOne() 方法里面就正常显示了
                    // TODO
                    // System.out.println(SemaphoreTest.count);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }
        // 打印的值不是预期的 10,因为子线程还没有执行完,主线程就执行完了
        System.err.println(SemaphoreTest.count);
    }
}

**请问为什么加在 SemaphoreTest.addOne(); 代码后面,打印count,会出现重复出现的情况** 

```java
2
2
3
6
5
4
8
7
9
10

Process finished with exit code 0


  • 写回答

2条回答 默认 最新

  • 八云黧 2021-08-17 16:00
    关注

    就是正常多线程的问题啊,你addOne内部用信号量实现互斥了,但print语句没有啊,比如a线程addOne执行完了,此时count为3,准备打印count,结果这时候换成b线程了,b线程addOne正常运行,count正常等于4,打印4,然后a线程回复运行,打印count就是4了,这不就打印两个4出来了吗

    评论

报告相同问题?

问题事件

  • 创建了问题 8月17日

悬赏问题

  • ¥15 vscode的问题提问
  • ¥50 切换TabTip键盘的输入法
  • ¥15 可否在不同线程中调用封装数据库操作的类
  • ¥15 微带串馈天线阵列每个阵元宽度计算
  • ¥15 keil的map文件中Image component sizes各项意思
  • ¥20 求个正点原子stm32f407开发版的贪吃蛇游戏
  • ¥15 划分vlan后,链路不通了?
  • ¥20 求各位懂行的人,注册表能不能看到usb使用得具体信息,干了什么,传输了什么数据
  • ¥15 Vue3 大型图片数据拖动排序
  • ¥15 Centos / PETGEM