我有一个关于多线程的问题。
基本上我有这个方法:
public void instructs(Pacman pacman) {
Iterator it = q.iterator();
Thread t = null;
while (it.hasNext()) {
try {
String function = q.remove();
if (t != null) t.join();
MovementUpdater mu = new MovementUpdater(pacman, function);
t = new Thread(mu);
t.start();
} catch (InterruptedException ex) {
}
}
}
MovementUpdater
类是一个Runnable,它包含function
的实现(例如:左转,右转)。因此,如果我只有1个函数定义,则线程t
可以正常工作。我的意思是pacman
(JLabel)能够更新它的Icon。
问题是当我有超过1 function
时,pacman
的图标仅从最后一个线程更新。 t.join()
似乎使pacman
未实时更新(更改其图标)。
那么,任何解决这个问题的想法 - 确保pacman
的图标在每个线程中实时更新?
package com.stiw5024.project.edugame.jpacman.engine.animation;
import com.stiw5024.project.edugame.jpacman.constants.BoardConstants;
import com.stiw5024.project.edugame.jpacman.constants.FacingConstants;
import com.stiw5024.project.edugame.jpacman.constants.MovementConstants;
import com.stiw5024.project.edugame.jpacman.engine.Pacman;
import javax.swing.SwingUtilities;
public class MovementUpdater implements Runnable {
private final Pacman pacman;
private final String function;
public MovementUpdater(Pacman pacman, String function) {
this.pacman = pacman;
this.function = function;
}
private void updateFacing(String previousFacing, String func) {
switch (previousFacing) {
case FacingConstants.FACE_UP: // 0 degree
switch (func) {
case MovementConstants.TURN_LEFT:
pacman.setFacing(FacingConstants.FACE_LEFT);
break;
case MovementConstants.TURN_RIGHT:
pacman.setFacing(FacingConstants.FACE_RIGHT);
break;
}
break;
case FacingConstants.FACE_DOWN: // 180 degrees
switch (func) {
case MovementConstants.TURN_LEFT:
pacman.setFacing(FacingConstants.FACE_RIGHT);
break;
case MovementConstants.TURN_RIGHT:
pacman.setFacing(FacingConstants.FACE_LEFT);
break;
}
break;
case FacingConstants.FACE_RIGHT: // 90 degrees
switch (func) {
case MovementConstants.TURN_LEFT:
pacman.setFacing(FacingConstants.FACE_UP);
break;
case MovementConstants.TURN_RIGHT:
pacman.setFacing(FacingConstants.FACE_DOWN);
break;
}
break;
case FacingConstants.FACE_LEFT: // 270 degrees
switch (func) {
case MovementConstants.TURN_LEFT:
pacman.setFacing(FacingConstants.FACE_DOWN);
break;
case MovementConstants.TURN_RIGHT:
pacman.setFacing(FacingConstants.FACE_UP);
break;
}
break;
}
}
@Override
public void run() {
int angle = 0;
int lastAngle;
switch (pacman.getFacing()) {
case FacingConstants.FACE_UP:
if (function.equals(MovementConstants.TURN_LEFT)) {
angle = 360;
}
break;
case FacingConstants.FACE_DOWN:
angle = 180;
break;
case FacingConstants.FACE_LEFT:
angle = 270;
break;
case FacingConstants.FACE_RIGHT:
angle = 90;
break;
}
try {
switch (function) {
case MovementConstants.TURN_LEFT:
lastAngle = angle - 90;
for (int a = angle; a >= lastAngle; a -= 5) {
final int currentAngle = a;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
if (currentAngle == 360) {
pacman.setIcon(BoardConstants.PACMAN[0]);
} else {
pacman.setIcon(BoardConstants.PACMAN[currentAngle]);
}
}
});
Thread.sleep(20);
}
break;
case MovementConstants.TURN_RIGHT:
lastAngle = angle + 90;
for (int a = angle; a <= lastAngle; a += 5) {
final int currentAngle = a;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
if (currentAngle == 360) {
pacman.setIcon(BoardConstants.PACMAN[0]);
} else {
pacman.setIcon(BoardConstants.PACMAN[currentAngle]);
}
}
});
Thread.sleep(20);
}
break;
case MovementConstants.ADVANCE:
break;
case MovementConstants.CLIMB_UP:
break;
case MovementConstants.EAT:
break;
}
updateFacing(pacman.getFacing(), function);
Thread.sleep(2000);
} catch (InterruptedException e) {
}
}
}