下面是我的整个类,大家感兴趣可以把这段代码复制到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();
}
}
是不是死锁了 Semaphore 是共享锁 线程third 不完成是不会让出锁
数据结构用错了,Semaphore只能限制并发,但是不能控制先后顺序
Foo类的代码发出来看看,有没有实现Runnable接口。
java我不熟悉,我感觉你信号没有用对。你third函数那边没有release,所以它占用了3个的时候second就没有了。
线程不执行 是指进行到哪一步不执行?
从你写的逻辑上来看,必须要控制first,second,third这个顺序,但是你写的main函数并不能保证一定是first先进入,second第二个进入,third第三个进入。如果first先进入了后释放了2个凭证,此时third进入了,程序就卡死了,中间加个thread.sleep(10)吧,保证一定是first,second,third这个顺序。其实你是无法保证哪条线程先执行,哪条线程在何时执行,完全由cpu来决定。当然大概率是first,second,third这个顺序