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

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

如何使用SwingWorker模擬緩沖的外圍設(shè)備?

如何使用SwingWorker模擬緩沖的外圍設(shè)備?

藍(lán)山帝景 2019-10-22 21:58:42
我將本練習(xí)用作教學(xué)工具,以幫助我掌握一些Java GUI編程概念。我要尋找的是一種一般的理解,而不是針對(duì)一個(gè)特定問(wèn)題的詳細(xì)解決方案。我希望編碼這種“正確的”方法將教給我很多有關(guān)如何解決將來(lái)的多線(xiàn)程問(wèn)題的知識(shí)。如果對(duì)于這個(gè)論壇來(lái)說(shuō)太籠統(tǒng)了,那么它可能屬于Programmers嗎?我在模擬讀卡器。它具有GUI,可讓我們將卡裝載到料斗中并按Start(開(kāi)始),依此類(lèi)推,但它的主要“客戶(hù)端”是CPU,在單獨(dú)的線(xiàn)程上運(yùn)行并請(qǐng)求卡。讀卡器維護(hù)一個(gè)緩沖區(qū)。如果有卡請(qǐng)求進(jìn)入并且緩沖區(qū)為空,則讀卡器必須從料斗讀取卡(這需要1/4秒,即1962)。在將卡讀入緩沖區(qū)后,讀卡器將緩沖區(qū)發(fā)送到CPU,并在下一個(gè)請(qǐng)求之前立即啟動(dòng)另一個(gè)緩沖區(qū)加載操作。如果不僅緩沖區(qū)是空的,而且料斗中沒(méi)有卡,那么我們必須等到操作員將一個(gè)平臺(tái)放在料斗中并按下啟動(dòng)鍵(這始終會(huì)啟動(dòng)緩沖區(qū)加載操作)。在我的實(shí)現(xiàn)中,卡請(qǐng)求以invokeLater() Runnables在EDT上排隊(duì)的形式發(fā)送到讀卡器。在myRunnable.run()時(shí)間,無(wú)論是一個(gè)緩沖器將可用(在這種情況下,我們可以將其發(fā)送到CPU和開(kāi)球另一個(gè)緩沖器負(fù)載操作),或緩沖區(qū)將是空的。如果是空的怎么辦??jī)煞N可能性:(a)飛行中已經(jīng)進(jìn)行了緩沖加載操作,或者(b)儲(chǔ)卡器為空(或尚未啟動(dòng))。無(wú)論哪種情況,都不能讓EDT等待。工作(和等待)必須在后臺(tái)線(xiàn)程上完成。為了簡(jiǎn)單起見(jiàn),我嘗試生成一個(gè)SwingWorker來(lái)響應(yīng)每個(gè)卡請(qǐng)求,而不管緩沖區(qū)的狀態(tài)如何。偽代碼為:SwingWorker worker = new SwingWorker<Void, Void>() {    public Void doInBackground() throws Exception {        if (buffer.isEmpty()) {            /*             * fill() takes 1/4 second (simulated by Thread.sleep)             * or possibly minutes if we need to have another              * card deck mounted by operator.             */            buffer.fill();        }        Card card = buffer.get(); // empties buffer        /*         * Send card to CPU         */        CPU.sendMessage(card); // <== (A) put card in msg queue        /*          * Possible race window here!!         */        buffer.fill(); //         <== (B) pre-fetch next card        return null;    }};worker.execute();這產(chǎn)生了一些奇怪的計(jì)時(shí)效果-我懷疑是buffer.fill()由于可能發(fā)生如下情況的比賽:如果在(A)和(B)之間,CPU收到了卡,發(fā)送了另一個(gè)請(qǐng)求,并有另一個(gè)SwingWorker線(xiàn)程代表它生成,則可能有兩個(gè)線(xiàn)程同時(shí)嘗試填充緩沖區(qū)。[刪除(B)處的預(yù)取調(diào)用解決了該問(wèn)題。]所以我認(rèn)為每次讀取都產(chǎn)生一個(gè)SwingWorker線(xiàn)程是錯(cuò)誤的??ǖ木彌_和發(fā)送必須在單個(gè)線(xiàn)程中序列化。該線(xiàn)程必須嘗試預(yù)取緩沖區(qū),并且如果我們的卡用完了并且必須等待將更多的內(nèi)存放入料斗中,則必須能夠等待并恢復(fù)。我懷疑SwingWorker擁有長(zhǎng)時(shí)間運(yùn)行的后臺(tái)線(xiàn)程才能處理此問(wèn)題,但我還沒(méi)有到位。假設(shè)要使用SwingWorker線(xiàn)程,我應(yīng)該如何實(shí)現(xiàn)這一點(diǎn),消除EDT的延遲,允許該線(xiàn)程阻塞等待裝滿(mǎn)料斗并處理在另一個(gè)卡請(qǐng)求到達(dá)之前或之后是否完成緩沖區(qū)填充的不確定性?
查看完整描述

3 回答

?
慕容3067478

TA貢獻(xiàn)1773條經(jīng)驗(yàn) 獲得超3個(gè)贊

了解內(nèi)部SwingWorker使用可能會(huì)有所幫助ExecutorService;為方便起見(jiàn),它添加了臨時(shí)EDT處理機(jī)制。只要您在EDT上更新GUI并同步對(duì)任何共享數(shù)據(jù)的訪(fǎng)問(wèn),則后者等效于前者。


假設(shè)您使用的是此處建議的“ 模型–視圖–控制器”模式,則模型是CPU的操作。盡管可能是不同的類(lèi),但我看不出有任何理由在不同的線(xiàn)程上對(duì)讀卡器進(jìn)行建模。相反,讓處理器模型具有讀卡器模型,該模型在線(xiàn)程上等待,并在計(jì)時(shí)器觸發(fā)時(shí)更新模型。讓更新的模型在將事件發(fā)布到EDT的正常過(guò)程中通知視圖。讓控制器根據(jù)查看手勢(shì)取消和安排讀卡器模型。java.util.Timer


查看完整回答
反對(duì) 回復(fù) 2019-10-22
?
繁星coding

TA貢獻(xiàn)1797條經(jīng)驗(yàn) 獲得超4個(gè)贊

我附加到原始問(wèn)題的“答案”中缺少一件事:


我正在Thread.sleep()通過(guò)單線(xiàn)程執(zhí)行程序?qū)⒑臅r(shí)的工作(僅用于教學(xué)目的)交給后臺(tái)線(xiàn)程。但是,出現(xiàn)了一個(gè)問(wèn)題,因?yàn)楹笈_(tái)線(xiàn)程正在通過(guò)輪詢(xún)(用作一個(gè)Swing組件的數(shù)據(jù)模型的)List來(lái)“讀取卡”,并引發(fā)了許多AWT數(shù)組索引超出范圍的異常。經(jīng)過(guò)幾次徒勞的嘗試使EDT和我的后臺(tái)線(xiàn)程同步對(duì)列表的訪(fǎng)問(wèn)之后,我進(jìn)行了調(diào)試,并將命令輪詢(xún)(包裝)到List(列表)并在一個(gè)小的Runnable()中更新了GUI,并使用invokeAndWait()導(dǎo)致當(dāng)我的后臺(tái)任務(wù)等待時(shí),它們將在EDT上運(yùn)行。


這是我修改后的解決方案:


private ExecutorService executorService;

 :

executorService = Executors.newSingleThreadExecutor();

 :

/*

 * When EDT receives a request for a card it calls readCard(),

 * which queues the work to the *single* thread.

 */

public void readCard() throws Exception {

    executorService.execute(new Runnable() {

        public void run() {

            if (buffer.isEmpty()) {

                /*

                 * fill() takes 1/4 second (simulated by Thread.sleep)

                 */

                buffer.fill();

            }

            Card card = buffer.get(); // empties buffer

            /*

             * Send card to CPU

             */

            CPU.sendMessage(card); // <== (A) put card in msg queue

            /* 

             * No race!  Next request will run on same thread, after us.

             */

            buffer.fill(); //         <== (B) pre-fetch next card

            return;

        }

    });

}


/*

 * IMPORTANT MODIFICATION HERE - - -

 *

 * buffer fill() method has to remove item from the list that is the

 * model behind a JList - only safe way is to do that on EDT!

 */

private void fill() {

    SwingUtilities.invokeAndWait(new Runnable() {

        /*

         * Running here on the EDT

         */

        public void run() {

            /*

             * Hopper not empty, so we will be able to read a card.

             */

            buffer = readHopper.pollLast();  // read next card from current deck

            fireIntervalRemoved(this, readHopper.size(), readHopper.size()); 

            gui.viewBottomOfHopper(); // scroll read hopper view correctly

        }

    });

    // back to my worker thread, to do 1/4 sec. of heavy number crunching ;)

    // while leaving the GUI responsive 

    Thread.sleep(250);

     :

    etc.

}


查看完整回答
反對(duì) 回復(fù) 2019-10-22
  • 3 回答
  • 0 關(guān)注
  • 427 瀏覽
慕課專(zhuān)欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號(hào)

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