2 回答
TA贡献1865条经验 获得超7个赞
你的代码没问题。您看到的输出可能会发生,因为插入到 messageBox 并打印消息不是原子的。
您在 Sender 中的代码可以像这样被拦截:
Sender Thread Receiver Thread
msgBox.put(i);
int element = msgBox.get();
System.out.println("Receiver got element : " + element);
System.out.println("Sender put element : " + i);
因此,在发送者放置元素之后和发送者打印消息之前,接收者能够首先获取该元素并打印消息,因为它在另一个线程中运行。在发送者将元素放入 messageBox 之前放置消息没有帮助,因为这样它可能会以另一种方式不一致:它打印元素已添加的消息,但由于某些原因不必实际添加例外。
如果您确实想有序地放置/接收消息,则必须将该消息放入 MessogeBox 方法中,如下所示:
public synchronized void put(E i)
{
msgQ.add(i);
System.out.println("Sender put element : " + i);
notify();
System.out.println(Thread.currentThread().getName() + " : notifying other threads...");
}
public synchronized E get()
{
if(msgQ.isEmpty())
{
try
{
System.out.println(Thread.currentThread().getName() + " : waiting for new element..");
notify();
wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
return msgQ.remove();
}
如果您仅在同步锁下访问 msgQ,则不必将 msgQ 设置为易失性。您还必须将 isEmpty 方法设置为同步,然后不必将 msgQ 设置为易失性。所以像这样修复你的代码:
public synchronized boolean isEmpty()
{
return msgQ.isEmpty();
}
TA贡献1946条经验 获得超3个赞
从 Sender 类更新您的打印语句
msgBox.put(i); System.out.println("Sender put element : " + i);
System.out.println("Sender put element : " + i); msgBox.put(i);
因为在您的情况下, MessageBox 放置了值,然后 Receiver 突然收到消息并打印,然后您的 print statementent 调用System.out.println("Sender put element : " + i);
。
添加回答
举报