[英]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.