[英]In Java, why is my multithreading not working?
首先,我這樣做:
public SpaceCanvas(){
new Thread(new Runnable () {//this is the thread that triggers updates, no kidding
int fcount = 0;
@Override
public void run() {
System.out.println("Update thread started!");
while(!Thread.interrupted()){
fcount++;
while(players.iterator().hasNext()){
players.iterator().next().update(fcount);
}
while(entities.iterator().hasNext()){
entities.iterator().next().update(fcount);
}
System.out.println("About to paint");
repaint();
System.out.println("Done with paints");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
players.add(new LocalPlayer(0, 9001, 0, 0, 0, 0, this, null));
}
在事物的初始值設定項中,我稱為SpaceCanvas。 但是,這不允許創建畫布及其內部的applet,因為Thread 實際上並不異步運行。 然后,我將“ .start()”替換為“ .run()”,該線程只運行了一次,但SpaceCanvas初始化完美。
我做錯了什么,該如何解決?
我不確定這種代碼是否可以按您期望的方式工作:
while(players.iterator().hasNext()){
players.iterator().next().update(fcount);
players.iterator()
為players
集合獲取一個新的迭代器。 如果集合中有0個項目,那么它將為false
但是如果有任何項目,您將處於無限循環中,每次都創建一個新的迭代器。 players
iterator()
內部的iterator()
調用也會生成另一個新的迭代器對象。
我認為您應該執行以下操作:
Iterator iterator = players.iterator();
while (iterator.hasNext()) {
iterator.next().update(fcount);
}
entities
循環也是如此。 更好的模式(從Java 5開始)是使用for
循環:
for (Player player : players) {
player.update(fcount);
}
另外,如果多個線程正在訪問這些集合,則必須以某種方式synchronized
。 您可以使用並發集合,也可以確保每次訪問(讀取和寫入)都在synchronized
塊內。
synchronized (players) {
for (Player player : players) {
player.update(fcount);
}
}
...
// down in the outer thread
synchronized (players) {
players.add(new LocalPlayer(0, 9001, 0, 0, 0, 0, this, null));
}
顯然, entities
將需要以相同的方式進行synchronized
。
JApplet/JPanel
)而不是AWT( Applet/Canvas
) Timer
,每500毫秒調用一次repaint()
。 Timer
)請勿在EDT(事件調度線程)上調用Thread.sleep(n)
)。 ..您可以使用JPanel嗎?
當然可以 為此,請重寫paintComponent(Graphics)
方法。 您也可以擴展JComponent
並執行相同的操作,但是處理JComponent
會有一些怪癖,使JPanel
成為擴展的更好選擇。
另一方面,完全有另一種方法。
BufferedImage
。 ImageIcon
。 JLabel
。 Timer
動作上。
image.getGraphics()
獲得繪圖表面。 paint()
或paintComponent()
所做的工作
Graphics
實例的dispose()
。 label.repaint()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.