Java 如何使用信号量发送信号?
现在我研究信号量。我在谷歌上搜索了以下关于这个主题的链接: 这个链接的作者写了关于使用信号量来发送信号的文章。为了展示它是如何工作的,他编写了自定义信号量 自定义信号灯代码:Java 如何使用信号量发送信号?,java,multithreading,concurrency,synchronization,semaphore,Java,Multithreading,Concurrency,Synchronization,Semaphore,现在我研究信号量。我在谷歌上搜索了以下关于这个主题的链接: 这个链接的作者写了关于使用信号量来发送信号的文章。为了展示它是如何工作的,他编写了自定义信号量 自定义信号灯代码: public class Semaphore { private boolean signal = false; public synchronized void take() { this.signal = true; this.notify(); } public synchroni
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...
}
}
}
主要内容:
据我所知,执行顺序如下
send - receive
send - receive
send - receive
...
我试图用这个bluerprint编写自己的代码
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");
}
}
}
因此,这不是我所期望的行为
我犯了一个错误,然后我写了代码或者我不理解这个概念
作者想说什么?找到更好的教程 您看到的输出与我预期的差不多。发送方线程从不阻塞,因此它将永远继续打印发送、发送、发送。同时,在接收方线程中,每次调用semaphore.release方法时,它都会被阻止,直到发送方下次运行为止 我希望看到很多发送消息,偶尔也会收到消息——或多或少是你所说的看到的 我不知道这个例子应该证明什么,但对我来说,它给人的印象是,作者不知道程序员期望信号量如何工作 一些作者提供了不做什么的示例,或者包含故意错误的示例,这些错误将在后面的示例中修复。你确定你没有效仿这样的例子吗
编辑:我跟踪了链接,看起来主要的问题是在take和release方法的定义中名称被交换了。如果您只是切换名称,这会更有意义。找到更好的教程 您看到的输出与我预期的差不多。发送方线程从不阻塞,因此它将永远继续打印发送、发送、发送。同时,在接收方线程中,每次调用semaphore.release方法时,它都会被阻止,直到发送方下次运行为止 我希望看到很多发送消息,偶尔也会收到消息——或多或少是你所说的看到的 我不知道这个例子应该证明什么,但对我来说,它给人的印象是,作者不知道程序员期望信号量如何工作 一些作者提供了不做什么的示例,或者包含故意错误的示例,这些错误将在后面的示例中修复。你确定你没有效仿这样的例子吗
编辑:我跟踪了链接,看起来主要的问题是在take和release方法的定义中名称被交换了。如果只是切换名称,则更有意义。在ReceivesFore启动时,SendSeFore已经执行了10次 考虑使用a同时启动两个线程。尽管正如Fuhrmanator所指出的,这不会产生您所寻找的交替输出
为此,我将使用一个有界信号量和一个信号。到ReceiveSemafore启动时,SendSemafore已经执行了10次 考虑使用a同时启动两个线程。尽管正如Fuhrmanator所指出的,这不会产生您所寻找的交替输出
为此,我将使用一个有界信号量和一个信号。@rpg711 System.out对于了解线程执行顺序是不可靠的。试试Thread.sleep1000;在接收中的while循环之前。@rpg711 System.out无法可靠地了解线程的执行顺序。试试Thread.sleep1000;在接收中的while循环之前。请在i++<10时检查此链接{System.out.printlnsend;10-发送计数messages@gstackoverflow,我跟踪了链接,该页面上的信息完全错误。在上一个示例中,他演示了如何将信号量用作互斥对象,他在进入关键部分之前调用semaphore.take,在离开该部分时调用semaphore.release。但是take的行为nd release与它们应该的正好相反。take方法应该是等待的方法,release方法应该是通知的方法。在他的互斥体示例中,任何数量的线程都可以同时进入关键部分,但只有一个线程会再次退出。我甚至不会将本文称为“教程”。它只是一堆代码片段和一些注释,远远小于相应Java类的API文档,也就是说,在i++<10时将其与此链接进行比较并请检查{System.out.printlnsend;10-发送计数messages@gstackoverflow,我跟踪了链接,该页面上的信息完全错误。在上一个示例中,他演示了如何将信号量用作互斥对象,他在进入关键部分之前调用semaphore.take,在离开该部分时调用semaphore.release。但是take的行为nd释放与它们应该的正好相反。take方法应该是
等待,发布方法应该是通知的方法。在他的互斥体示例中,任何数量的线程都可以同时进入关键部分,但只有一个线程可以再次退出,我甚至不会将本文称为“教程”。它只是一堆代码片段和一些注释,比相应Java类的API文档要小得多,也就是说,将其与Java类进行比较,并且,我认为如果您多次运行此程序,在接收之前发送消息的数量并不总是相同的。即使使用倒计时锁存器,仅仅因为您同时启动线程,并不意味着它们每次都以相同的方式执行。我只想介绍一个线程;在发送方开始时延迟它,以确保接收方在第一次发送之前先等待。@maxmil无论如何,代码不应依赖于Thread.sleep。这个概念是错误的。而且,我认为如果你多次运行这个程序,在接收之前发送消息的数量并不总是相同的。即使使用倒计时锁存器,仅仅因为您同时启动线程,并不意味着它们每次都以相同的方式执行。我只想介绍一个线程;在发送方开始时延迟它,以确保接收方在第一次发送之前先等待。@maxmil无论如何,代码不应依赖于Thread.sleep。这个概念是错误的。
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