Java-两个线程通过wait()/notify()进行通信,但线程交替运行,线程先获得锁
该方案的预期产出是: 平 庞 发出砰的声响 庞 发出砰的声响 庞 然而,它在这两者之间交替 庞 发出砰的声响 等等 问题是,我创建了Ping线程并首先运行它。所以我不知道为什么Pong偶尔会排在第一位 这是我的代码(易于编译)。从本质上讲,它是有效的。我只是不明白为什么有时候它会先打印“Pong”。有人能解释一下为什么会这样吗Java-两个线程通过wait()/notify()进行通信,但线程交替运行,线程先获得锁,java,multithreading,synchronization,synchronized,Java,Multithreading,Synchronization,Synchronized,该方案的预期产出是: 平 庞 发出砰的声响 庞 发出砰的声响 庞 然而,它在这两者之间交替 庞 发出砰的声响 等等 问题是,我创建了Ping线程并首先运行它。所以我不知道为什么Pong偶尔会排在第一位 这是我的代码(易于编译)。从本质上讲,它是有效的。我只是不明白为什么有时候它会先打印“Pong”。有人能解释一下为什么会这样吗 // Printer class - will be the object that both threads lock / synchronize onto class
// Printer class - will be the object that both threads lock / synchronize onto
class Printer
{
int numberOfMessages;
int messageCount;
// Constructor allowing user to choose how many messages are displayed
Printer(int numberOfMessages)
{
this.numberOfMessages = numberOfMessages;
this.messageCount = 0;
}
// If more messages are to be printed, print and increment messageCount
void printMsg(String msg)
{
if (messageCount < numberOfMessages)
{
System.out.println("[" + msg + "]");
++messageCount;
}
else
{
System.exit(0);
}
}
}
// PingPong thread
class PingPongThread extends Thread
{
Printer printer;
String message;
public PingPongThread(Printer printer, String message)
{
this.printer = printer;
this.message = message;
this.start();
}
@Override
public void run()
{
while(true)
{
synchronized (printer)
{
// Print message whether it is Ping or Pong
printer.printMsg(message);
// Notify
printer.notify();
// Wait
try
{
printer.wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
}
// Two threads communicate with eachother to alteratively print out "Ping" and "Pong"
public class PingPong
{
public static void main(String args[])
{
Printer printer = new Printer(6);
PingPongThread pingThread = new PingPongThread(printer, "Ping");
PingPongThread pongThread = new PingPongThread(printer, "Pong");
}
}
//打印机类-将是两个线程锁定/同步到的对象
类打印机
{
int numberOfMessages;
int-messageCount;
//构造函数,允许用户选择显示多少条消息
打印机(int numberOfMessages)
{
this.numberOfMessages=numberOfMessages;
this.messageCount=0;
}
//如果要打印更多消息,请打印并增加messageCount
无效打印消息(字符串消息)
{
if(messageCount
因为run
方法在不同的线程中运行,除非进行了适当的同步,否则无法假定哪个线程将首先运行。如果线程先开始,并不意味着它会更重要。所有动物都是平等的
您应该在线程中创建一个特殊的标志,当线程启动时会收到通知。并在启动第二个线程之前等待标志。做这件事的简单方法是使用。因为
run
方法在不同的线程中运行,除非进行了适当的同步,否则您无法假定哪个线程将首先运行。如果线程先开始,并不意味着它会更重要。所有动物都是平等的
您应该在线程中创建一个特殊的标志,当线程启动时会收到通知。并在启动第二个线程之前等待标志。执行此操作的简单方法是使用。您希望强制线程按顺序运行。JVM不能保证这一点,因此您必须自己动手。我可以想出两种解决办法 丑陋的黑客,但可能会工作:在启动第一个线程之后,但在启动第二个线程之前,产生当前线程,以“鼓励”它运行。例如:
PingPongThread pingThread = new PingPongThread(printer, "Ping");
Thread.yield();
PingPongThread pongThread = new PingPongThread(printer, "Pong");
这是最简单的解决方案,但不能保证每次都能正常工作,例如,如果另一个线程(比如,事件处理程序)在屈服后抓住控件
更健壮的方法是:让主线程在启动第二个线程之前等待其他信号。假设该信号通过一个名为lock
的字段传递,这将类似于:
Object lock = new Object();
PingPongThread pingThread = new PingPongThread(lock, printer, "Ping");
lock.wait();
PingPongThread pongThread = new PingPongThread(lock, printer, "Pong");
线程run()
方法如下
synchronize (lock) { lock.notify(); }
while (true) {
// As before...
}
您想强制线程按顺序运行。JVM不能保证这一点,因此您必须自己动手。我可以想出两种解决办法 丑陋的黑客,但可能会工作:在启动第一个线程之后,但在启动第二个线程之前,产生当前线程,以“鼓励”它运行。例如:
PingPongThread pingThread = new PingPongThread(printer, "Ping");
Thread.yield();
PingPongThread pongThread = new PingPongThread(printer, "Pong");
这是最简单的解决方案,但不能保证每次都能正常工作,例如,如果另一个线程(比如,事件处理程序)在屈服后抓住控件
更健壮的方法是:让主线程在启动第二个线程之前等待其他信号。假设该信号通过一个名为lock
的字段传递,这将类似于:
Object lock = new Object();
PingPongThread pingThread = new PingPongThread(lock, printer, "Ping");
lock.wait();
PingPongThread pongThread = new PingPongThread(lock, printer, "Pong");
线程run()
方法如下
synchronize (lock) { lock.notify(); }
while (true) {
// As before...
}
JVM不保证线程将按照启动顺序启动。这就是为什么有时第二个线程首先启动。JVM不能保证线程按照启动顺序启动。这就是为什么有时第二个线程首先启动。如果创建两个线程,例如
t1
和t2
,然后调用:
t1.start();
t2.start();
这并不意味着
t1
将在t2
之前开始执行。可能是这样,但有可能t2
会首先启动。您必须编写自己的方法,保证首先从t1
开始。例如,在启动第一个线程后,如果您创建了两个线程(例如t1
和t2
),则在对象上的wait()
和run()的开头在该对象上的第一个线程notify()
中,然后调用:
t1.start();
t2.start();
这并不意味着t1
将在t2
之前开始执行。可能是这样,但有可能t2
会首先启动。您必须编写自己的方法,保证首先从t1
开始。例如,启动后