第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

線程問題 - 接收方在發(fā)送方之前打印

線程問題 - 接收方在發(fā)送方之前打印

12345678_0001 2024-01-28 20:28:35
我試圖找出 java 中的線程,并試圖理解我得到的輸出。我創(chuàng)建了 3 個類:發(fā)送者、接收者和消息框。我正在嘗試通過消息框?qū)?shù)據(jù)從發(fā)送者發(fā)送到接收者。當(dāng)發(fā)送方發(fā)送數(shù)據(jù)時,它會打印“發(fā)送方放置元素”。一旦接收者獲得一個元素,它就會打印“接收者獲得元素”問題是,在控制臺中,我看到接收者打印出他在發(fā)送者打印出他發(fā)送了該元素之前獲得了該元素。發(fā)件人:public class Sender implements Runnable {    private MessageBox msgBox;    public Sender(MessageBox m)    {        msgBox=m;    }    public void run()    {        Thread.currentThread().setName("Sender");        for(int i=0;i< 100;i++)        {            msgBox.put(i);            System.out.println("Sender put element : " + i);            try {                long sleep_time = (long)(Math.random()*5000);                //System.out.println("Sender going to sleep for " + sleep_time + " ms");                Thread.sleep(sleep_time);            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}接收者 :public class Receiver implements Runnable{    private MessageBox<Integer>  msgBox;    public Receiver(MessageBox<Integer>m)    {        msgBox = m;    }    public void run()    {        Thread.currentThread().setName("Receiver");        while(true)        {                int element = msgBox.get();                System.out.println("Receiver got element : " + element);            try            {                long sleep_time = (long)(Math.random()*5000);                //System.out.println("Receiver going to sleep for " + sleep_time + " ms");                Thread.sleep(sleep_time);            }            catch (InterruptedException e)            {                e.printStackTrace();            }        }    }}
查看完整描述

2 回答

?
莫回?zé)o

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();

    }


查看完整回答
反對 回復(fù) 2024-01-28
?
智慧大石

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);。


查看完整回答
反對 回復(fù) 2024-01-28
  • 2 回答
  • 0 關(guān)注
  • 200 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號