Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java join()方法存在问题_Java_Multithreading - Fatal编程技术网

Java join()方法存在问题

Java join()方法存在问题,java,multithreading,Java,Multithreading,首先,这里有一些代码片段: public void startThread() { this.animationThread = new Thread(this); this.animationThread.start(); try { this.animationThread.join(); } catch (InterruptedException e) { e.printStackTrace(); } } @Over

首先,这里有一些代码片段:

public void startThread() {
    this.animationThread = new Thread(this);
    this.animationThread.start();
    try {
        this.animationThread.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

@Override
public void run() {     
    pirateMainAnimation.animate();
}

public void animate() {
    for (int j = 0; j < 9; j++) {
        try {
            Thread.sleep(250);
        } catch (InterruptedException e) {
            break;
        }
        PirateAnimationPanel.getInstance().setCurrent(j);
        PirateAnimationPanel.getInstance().repaint();
    }
}
public void startThread(){
this.animationThread=新线程(this);
这个.animationThread.start();
试一试{
this.animationThread.join();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
@凌驾
public void run(){
盗版动画。动画();
}
public void animate(){
对于(int j=0;j<9;j++){
试一试{
睡眠(250);
}捕捉(中断异常e){
打破
}
PirateAnimationPanel.getInstance().setCurrent(j);
PirateAnimationPanel.getInstance().repaint();
}
}
我正在尝试制作一些图像的动画。我希望主线程等待动画线程完成,然后继续。我四处搜索,读了一些书,决定使用join()方法。它完美地等待线程完成,但我没有正确地设置动画。repaint()方法被调用2次而不是9次。我想问题可能是因为我使用了单身。这里是单例实现

import java.awt.Graphics;
import java.awt.MediaTracker;

import javax.swing.JPanel;

import uk.ac.aber.dcs.piratehangman.animation.PirateMainAnimation;
import uk.ac.aber.dcs.piratehangman.utilityclasses.AnimationThread;

@SuppressWarnings("serial")
public class PirateAnimationPanel extends JPanel {
    private int current;
    private MediaTracker mTracker;
    private PirateMainAnimation pirateMainAnimation;
    private AnimationThread animationThread;

    private PirateAnimationPanel() {
        this.current = 0;
        this.pirateMainAnimation = new PirateMainAnimation();
        mTracker = new MediaTracker(this);
        this.animationThread = new AnimationThread();
        setMediaTracker();
        repaint();
    }

    private void setMediaTracker() {
        for (int i = 0; i < 9; i++) {
            mTracker.addImage(
                    this.pirateMainAnimation.getImagesForAnimation()[i],
                    this.pirateMainAnimation.getImagesForAnimationID()[i]);
            try {
                mTracker.waitForID(this.pirateMainAnimation
                        .getImagesForAnimationID()[i]);
            } catch (InterruptedException e) {
                System.out.println("Error loading image: " + i);
            }
        }
    }

    public void playAnimation() {
        this.animationThread.startThread();
    }

    public void paintComponent(Graphics g) {
        super.paintComponents(g);
        System.out.println("called");
        g.drawImage(this.pirateMainAnimation.getImagesForAnimation()[current],
                0, 0, this);
    }

    private static class PirateAnimationPanelHolder {
        private static final PirateAnimationPanel pirateAnimationPanel =
            new PirateAnimationPanel();
    };

    public static PirateAnimationPanel getInstance() {
        return PirateAnimationPanelHolder.pirateAnimationPanel;
    }

    public void setCurrent(int current) {
        this.current = current;
    }

    public int getCurrent() {
        return current;
    }
}
导入java.awt.Graphics;
导入java.awt.MediaTracker;
导入javax.swing.JPanel;
进口uk.ac.aber.dcs.piratehangman.animation.PirateManimation;
导入uk.ac.aber.dcs.piratehangman.utilityplasses.AnimationThread;
@抑制警告(“串行”)
公共类PirateAnimationPanel扩展了JPanel{
私有电流;
私人媒体追踪者;
私人盗版;
私有AnimationThread AnimationThread;
private PirateAnimation Panel(){
该电流=0;
this.pirateManimation=新的pirateManimation();
mTracker=新的MediaTracker(本);
this.animationThread=新的animationThread();
setMediaTracker();
重新油漆();
}
私有void setMediaTracker(){
对于(int i=0;i<9;i++){
mTracker.addImage(
this.pirateManimation.getImagesForAnimation()[i],
this.pirateManimation.getImagesForAnimationID()[i]);
试一试{
mTracker.waitForID(this.pirateManimation
.getImagesForAnimationID()[i]);
}捕捉(中断异常e){
System.out.println(“加载图像时出错:+i”);
}
}
}
公开播放动画(){
this.animationThread.startThread();
}
公共组件(图形g){
超级组件(g);
System.out.println(“被调用”);
g、 drawImage(this.pirateManimation.getImagesForAnimation()[current],
0,0,这个),;
}
私有静态类PirateAnimationPanelHolder{
私有静态最终盗版图像面板盗版图像面板=
新的PirateAnimationPanel();
};
公共静态盗版ImationPanel getInstance(){
返回PirateAnimationPanelHolder.pirateAnimationPanel;
}
公共void setCurrent(int current){
这个电流=电流;
}
public int getCurrent(){
回流;
}
}

我想您的意思是paintComponent()方法只会被调用两次。此外,我认为如果将组件填充为背景色,则应该能够删除对super.paintComponents()的调用

repaint()方法仅将组件标记为脏组件,并在下一次绘制时请求重新渲染

我本来希望Swing线程能够在250ms内重新绘制,但我不确定还有哪些工作正在进行/呈现。您可能希望在动画之前调用MediaTracker.waitForAll()

虽然静态单例没有添加太多内容,但我认为它不会导致问题(在本例中)

更新: 所以问题在于join()位于Swing事件线程上,该线程阻止了组件的重新绘制。我建议进行如下调用,以在最后一个动画之后显示“新建游戏对话框”:

SwingUtilities.invokeLater(new Runnable() {
    public void run() { showDialog(); }
})
“请注意,发布到的事件可以合并”,这可能解释了这种差异。此外,一定要在其上构建GUI。有关更详细的讨论,请参阅


附录:有一个很好的
SwingWorker
示例,可以简化卸载过程。

考虑将代码作为问题的一部分发布,而不是放在其他地方。如果您需要帮助将其正确格式化,只需说出来,我很乐意为您编辑代码。我认为在这里发布代码只会妨碍您的工作stion。不管怎样,如果你能帮我做格式化,我会很高兴,因为我从来没有在这里发布过代码。谢谢:)。当然,要在上面格式化代码,只需在每行前面缩进四个空格。我会在代码中编辑,如果你点击“编辑”,你就能明白我的意思。欢迎来到StackOverflow顺便说一句:)还有,我注意到你了在你的文本中使用了制表符,这也必须被编辑掉,并替换为空格。无论如何,代码被编辑进去。为了回答你在评论中暗示的问题,不,这里的代码不会妨碍问题的解决,只要它的大小与你的一样,代码就会脱颖而出,因此很容易看到什么是代码,什么是代码问题。再次感谢你善良的先生:)。我很高兴受到这样的欢迎。:)谢谢你的回答,有趣的是,当对join()方法的调用从代码中删除时。它工作正常。非常奇怪,我会尝试你的想法。所以“动画线程”在上次调用repaint()后退出/停止可以在渲染完成之前进行。是否允许应用程序在连接和不连接的情况下继续?是什么触发了playAnimation(),它是从Swing线程(鼠标/按键事件或小程序)调用的?编辑:缺少wordplayAnimation()由JButton调用,但这取决于特定的条件。逻辑大致如下。用户在文本字段中输入一个单词,然后按下按钮