【问题标题】:Java Thread does not terminateJava 线程不终止
【发布时间】:2012-08-28 07:11:08
【问题描述】:

当两个三角形被点击两次时,我试图为一个三角形设置动画。一旦我单击它们两次三角形0开始移动直到moveX达到20,while(moveX

public class secondFrame extends JFrame implements Runnable {

}


public secondFrame(ChallengesDialog dialog) {

    component = new secFrameDrawComponent();
    createComponent();

    Thread t = new Thread(this);
    t.start();
}

private void createComponent() {

    sGen = new shapeGenerator(434, 231);

    createT();
}

class AddComponentListener implements MouseListener {

    public void mouseClicked(MouseEvent event) {


    for(int i = 0; i < count; i++) {
        if (component.getTri(i).contains(event.getX(), event.getY())) {
            component.setShapeFill("triangle", i);
            component.repaint();    

            countColors(i);

            setChallenge();
        }
...
MouseListener listener = new AddComponentListener();
component.addMouseListener(listener);                       

public void setChallenge() {

    //two red triangles
    if(challenge == 1 && triColorCount[1] == 2) {
        Thread t = new Thread(component);
        t.start();

        System.out.println("Thread's state: " + t.getState());

        if(t.getState() == Thread.State.TERMINATED) {
            //Unreachable
            System.out.println("Thread completed");
        }                   
    }
}
...

public void run() {

    while(threadFlag) { 
        ..
        timeLabel.setText("Elapsed time: " + elapsedTime);
        ..                      
    }
 }

public class secFrameDrawComponent extends JComponent implements Runnable {

    public void modTriangle(int x, int y) {

        sGen.setTriangleOffset(x, y);

        triangle[0] = sGen.getTriangle();
    }

    public void paintComponent(Graphics g) {

        Graphics2D g2 = (Graphics2D)g;

        draw(g2);       
    }

    public void run() {

        while(moveX < 20) {

            moveX+= 1;
            modTriangle(moveX, 0);
            repaint();

            try {
                Thread.sleep(170);
            } catch (InterruptedException e) {  
                e.printStackTrace();
            }
            System.out.println("moveX = " + moveX);
        }
        System.out.println("Thread completed exec");        
    }

    public void draw(Graphics2D g2) {

        g2.setStroke(new BasicStroke(2));

        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
            RenderingHints.VALUE_ANTIALIAS_ON);


        modTriangle(moveX, 0);
        g2.draw(triangle[0]);
        g2.draw(triangle[1]);
    }

【问题讨论】:

  • 线程运行需要多长时间?在检查线程终止之前等待多长时间?
  • 很可能当您在另一个线程中检查终止时,您的任务甚至没有被安排。在获取状态之前添加一些睡眠,看看会发生什么。
  • 我认为 zeller 的评论是正确的。
  • 如果我添加 System.out.println("线程的状态:" + t.getState());尝试 { t.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } 它达到终止状态但动画不显示
  • @user1420482 这很有意义,因为您已经等待线程完成,但您已阻止 GUI 线程,因此您看不到任何更新。

标签: java multithreading runnable implements


【解决方案1】:

仔细看看你在做什么。您开始一个新线程,然后立即检查它是否已终止。当然不会,动画完成需要一段时间。如果要等到线程完成,请使用join() 函数。但是请注意,这将阻塞调用线程,直到您“加入”的线程完成。

【讨论】:

  • 是的,如果另一个线程依赖于状态,阻塞应该不是问题。
  • @zeller 通常是这样。不过,这可能是 GUI 应用程序中不希望出现的行为,因为它会阻塞事件处理线程,从而有效地“冻结”界面,直到动画线程完成。
  • 你是对的,在这种情况下,用户线程应该轮询任务线程的状态,或者任务完成后应该通知主线程(但这有点离题......)
  • 在动画线程 .sleep(millis) 或 .join() 时是否有不“冻结”界面的解决方法?
  • @user1420482 是的。不要等待动画完成,让它顺其自然。
猜你喜欢
  • 2014-11-18
  • 2015-12-21
  • 2011-08-11
  • 1970-01-01
  • 2023-03-28
  • 2014-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多