2 回答

TA貢獻(xiàn)1865條經(jīng)驗(yàn) 獲得超7個贊
你的代碼沒問題。您看到的輸出可能會發(fā)生,因?yàn)椴迦氲?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);
因此,在發(fā)送者放置元素之后和發(fā)送者打印消息之前,接收者能夠首先獲取該元素并打印消息,因?yàn)樗诹硪粋€線程中運(yùn)行。在發(fā)送者將元素放入 messageBox 之前放置消息沒有幫助,因?yàn)檫@樣它可能會以另一種方式不一致:它打印元素已添加的消息,但由于某些原因不必實(shí)際添加例外。
如果您確實(shí)想有序地放置/接收消息,則必須將該消息放入 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 設(shè)置為易失性。您還必須將 isEmpty 方法設(shè)置為同步,然后不必將 msgQ 設(shè)置為易失性。所以像這樣修復(fù)你的代碼:
public synchronized boolean isEmpty()
{
return msgQ.isEmpty();
}

TA貢獻(xiàn)1946條經(jīng)驗(yàn) 獲得超3個贊
從 Sender 類更新您的打印語句
msgBox.put(i); System.out.println("Sender put element : " + i);
System.out.println("Sender put element : " + i); msgBox.put(i);
因?yàn)樵谀那闆r下, MessageBox 放置了值,然后 Receiver 突然收到消息并打印,然后您的 print statementent 調(diào)用System.out.println("Sender put element : " + i);
。
添加回答
舉報