Thread.join()导致组件更新冻结

时间:2016-05-11 16:10:41

标签: java multithreading

我有一个关于多线程的问题。

基本上我有这个方法:

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) {
        }
    }

}

0 个答案:

没有答案