漏出你的后槽牙 2021-08-12 15:11 采纳率: 0%
浏览 140
已结题

关于Semaphore中acquire方法的一个问题,信号量足够acquire了,但是线程不执行,我傻了……

下面是我的整个类,大家感兴趣可以把这段代码复制到ide中执行一下,我用的是jdk1.8。
是我在做leetcode的时候碰到的一个题:1114按序打印那个问题,然后我写了这么一段代码
因为想节约内存,所以想着只用一个Semaphore来解决,但是问题是第二个线程只需要2个通行证就可以执行,第一个线程执行完后还剩了2个通行证啊,但是第二个线程他就是卡在那了!

我大致解释下下面的代码吧:
1、Semaphore是java中的一个并发工具类(Doug Lea写的)
2、first,second,third方法的目的只是为了打印。这是leetcode留的打印入口不能删除,所以就留在了这里。
3、main方法中是我自己写的测试,大致就是按照leetcode中的题mu要求启动了三个线程后分别调用first,second,third方法
4、整道题的目的是为了按照顺序打印出first和second和third这三个字符串
有懂得的coder来支援下啊!!蒙了已经……
public class Foo {

private volatile Semaphore semaphore;

public Foo() {
    semaphore = new Semaphore(0);
}

public void first(Runnable printFirst) throws InterruptedException {
    // printFirst.run() outputs "first". Do not change or remove this line.
    System.out.println("需要0个许可证");
    printFirst.run();
    System.out.println("1执行");
    semaphore.release(2);
}

public void second(Runnable printSecond) throws InterruptedException {
    System.out.println("需要2个许可证");
    semaphore.acquire(2);
    // printSecond.run() outputs "second". Do not change or remove this line.
    printSecond.run();
    System.out.println("2执行");
    semaphore.release(3);
}

public void third(Runnable printThird) throws InterruptedException {
    System.out.println("需要3个许可证");
    semaphore.acquire(3);
    // printThird.run() outputs "third". Do not change or remove this line.
    printThird.run();
    System.out.println("3执行");
}

public static void main(String[] args) {
    Foo foo = new Foo();
    // 打印first的线程
    Thread first = new Thread(() -> {
        try {
            foo.first(() -> System.out.println("first"));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    });
    first.setName("first");
    first.start();
    // 打印second的线程
    Thread second = new Thread(() -> {
        try {
            foo.second(() -> System.out.println("second"));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    });
    second.setName("second");
    second.start();
    // 打印third的线程
    Thread third = new Thread(() -> {
        try {
            foo.third(() -> System.out.println("third"));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    });
    third.setName("third");
    third.start();
    new Thread(()-> {
        while (true){
            System.out.println("可用许可证:"+foo.semaphore.availablePermits());
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }).start();
}

}

  • 写回答

6条回答 默认 最新

  • 我是真的菜(ㄒoㄒ) 2021-08-12 16:39
    关注

    是不是死锁了 Semaphore 是共享锁 线程third 不完成是不会让出锁

    评论

报告相同问题?

问题事件

  • 系统已结题 8月20日
  • 赞助了问题酬金 8月12日
  • 创建了问题 8月12日