我正在尝试打印字符组合。
字符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;
}
首先,考虑为线程创建两个不同的类(可能是常见的抽象超类),而不是run()中的 if/else
fork。
现在,看信号级课程,请务必在该页面开头阅读描述,理解该概念确实很有帮助。基本上,您需要两种方法:acquire
和release
。每次打印" 2"时,都会调用release
方法。这增加了信号量保留的"许可"数量。现在,在另一个线程中,在打印" 3"之前,您将调用acquire
,它将检查是否有任何许可,如果没有许可,它将阻止并等待,否则,它将减少数字,并返回,以便您可以打印" 3"。当您以这种方式使用它时,信号量在任何给定时刻持有的许可证的数量将反映出比到目前为止" 3" S多的" 2" s。永远不会有3s的3s,因为acquire
不允许允许允许的数量为负,如果恰好是0,它将迫使您的线程等到另一个打印另一个" 2"并调用"释放"。