我试图打印一组字符。
字符1和2必须按顺序排列如下:1212121212。字符3间歇打印,但不得超过字符2.
我已经完成了任务的第一部分(1和2),但是在介绍3时我很挣扎。我知道我需要使用计数信号量来破解它。
这是针对学校的,所以请你能避免粘贴任何代码并给我一些指示吗?我只是展示了两个类:我的缓冲区和打印字符的线程。
感谢。
public class PrintLetterA extends Thread {
private char letter;
private Buffer buffer;
public PrintLetterA(char letter, Buffer b) {
this.letter = letter;
buffer = b;
}
public void run() {
while (true) {
if (letter == 'F') {
Object a = new Object();
buffer.put(a);
System.out.println("" + letter);
try {
Thread.sleep( (int) Math.random() * 100);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else if (letter == 'G'){
Object a = buffer.get();
System.out.println("" + letter);
try {
Thread.sleep( (int) Math.random() * 100);
} catch (InterruptedException e) {
e.printStackTrace();
}
public class Buffer {
private Object message = null;
BinarySemaphore Fbinary = new BinarySemaphore(1);
BinarySemaphore Gbinary = new BinarySemaphore(0);
public synchronized void put(Object message) {
try {
Fbinary.P();
} catch (InterruptedException e) {
e.printStackTrace();
}
this.message = message;
Gbinary.V();
}
public synchronized Object get() {
try {
Gbinary.P();
} catch (InterruptedException e) {
e.printStackTrace();
}
Object m = message;
Fbinary.V();
return m;
}
答案 0 :(得分:0)
首先,考虑为你的线程创建两个不同的类(可能还有一个常见的抽象超类)而不是run()中的if/else
fork。
现在,看看Semaphore class,请务必阅读该页面开头的说明,了解这个概念真的很有帮助。基本上,您关注的方法有两种:acquire
和release
。每次打印“2”时,都会调用release
方法。这增加了信号量持有的“许可”数量。现在,在另一个线程中,在打印“3”之前,你将调用acquire
,它会检查是否有可用的许可证,如果没有,它将阻塞并等待,否则,它将减少数字和返回,以便您可以打印“3”。
当你以这种方式使用它时,信号量在任何给定时刻持有的许可数量将反映到目前为止打印的“2”多于“3”。永远不会有超过2的3s,因为acquire
将不允许允许的数量为负数,如果它恰好是0,它将强制你的线程等到另一个打印另一个“2”并调用“释放”。