3 回答

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

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.
}
添加回答
舉報(bào)