现在我研究信号量。我用谷歌搜索了以下关于这个主题的链接:
此链接的作者撰写了有关使用信号量进行信号发送的文章。为了展示它是如何工作的,他编写了自定义信号量。
自定义信号量代码:
public class Semaphore {
private boolean signal = false;
public synchronized void take() {
this.signal = true;
this.notify();
}
public synchronized void release() throws InterruptedException{
while(!this.signal) wait();
this.signal = false;
}
}
关于如何在他写的代码中使用它如下:
public class SendingThread {
Semaphore semaphore = null;
public SendingThread(Semaphore semaphore){
this.semaphore = semaphore;
}
public void run(){
while(true){
//do something, then signal
this.semaphore.take();
}
}
}
public class RecevingThread {
Semaphore semaphore = null;
public ReceivingThread(Semaphore semaphore){
this.semaphore = semaphore;
}
public void run(){
while(true){
this.semaphore.release();
//receive signal, then do something...
}
}
}
主要内容:
Semaphore semaphore = new Semaphore();
SendingThread sender = new SendingThread(semaphore);
ReceivingThread receiver = new ReceivingThread(semaphore);
receiver.start();
sender.start();
据我了解执行顺序应遵循
send - receive
send - receive
send - receive
...
我尝试使用这个蓝图编写自己的代码
public class SendReceiveWithCustomSemaphore {
public static void main(String[] args) {
MySemaphore mySemaphore = new MySemaphore();
new Send(mySemaphore).start();
new Receive(mySemaphore).start();
}
}
class MySemaphore {
boolean flag = false;
public synchronized void take() throws InterruptedException {
flag = true;
notify();
}
public synchronized void release() throws InterruptedException {
while (!flag) {
wait();
}
flag = false;
}
}
class Send extends Thread {
MySemaphore mySemaphore;
public Send(MySemaphore semaphore) {
this.mySemaphore = semaphore;
}
@Override
public void run() {
int i = 0;
while (i++ < 10) {
System.out.println("send");
try {
mySemaphore.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Receive extends Thread {
MySemaphore mySemaphore;
public Receive(MySemaphore semaphore) {
this.mySemaphore = semaphore;
}
@Override
public void run() {
while (true) {
try {
mySemaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("receive");
}
}
}
输出:
send
send
send
send
send
send
send
send
send
send
receive
因此这不是我预期的行为。
我写代码时犯了错误还是我不理解概念?
作者想表达什么?
最佳答案
寻找更好的教程。
您看到的输出与我所期望的差不多。 “sender”线程从不阻塞,所以它将永远打印“send”、“send”、“send”。同时,在“接收方”线程中,每次调用 semaphore.release() 方法时,它将被阻塞,直到发送方下次运行。
我希望看到很多“发送”消息,偶尔会混入“接收”消息——或多或少如您描述的那样。
我不知道这个例子应该证明什么,但对我来说,它给人的印象是作者不知道程序员如何期望信号量的行为。
一些作者提供了不应该做的事的例子,或者包含将在后面的例子中“修正”的蓄意错误的例子。您确定您没有在遵循此类示例吗?
编辑:我点击了链接,看起来主要问题是在 take() 和 release() 方法的定义中交换了名称。如果只是切换名称,则更有意义。
关于java - 如何使用信号量进行信号发送?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23255267/