线程没有在Java中恢复?

时间:2015-02-04 14:44:13

标签: java multithreading swing synchronization

我正在使用线程将图像绘制到JFrame上 我添加了一个keyListener来监听键 P ,当按下它时,图像的绘制停止,当我再次按 P 时,绘图应该恢复。

我尝试使用wait / notify和synchronized块来实现这一点 然而,只有暂停工作,简历永远不会奏效 奇怪...

public static void main(String[] args)
{       
    static JFrame window1 = new JFrame();
    static boolean isPaused=false;
    Runnable r = new Runnable()
    {
         public void run()
         {
             while(true)
             {
                 window1.paintImage();//fn to redraw an image
             }
         }
    };

    final Thread t = new Thread(r);

    window1.addKeyListener(new KeyListener()
    {
        public void keyPressed(KeyEvent e)
        {
            if(e.getKeyCode() == KeyEvent.VK_P)
            {
                if(isPaused==false)
                {
                    synchronized(t)
                    {
                        try
                        {
                            t.wait();
                        } catch (InterruptedException e1)
                        {
                            e1.printStackTrace();
                        }
                    }
                    isPaused=true;
                } else
                {
                    t.notifyAll();
                    isPaused=false;
                }
            }
        }
        public void keyReleased(KeyEvent arg0){}
        public void keyTyped(KeyEvent arg0){}

    });


    t.start();
  }
}

1 个答案:

答案 0 :(得分:1)

您应该浏览Object.wait的{​​{3}}。 执行t.wait()时,当前主题“暂停”,而不是t。 更确切地说,您正在暂停负责处理输入的SWING线程,而不是您为重绘图像而创建的Thread tt.wait()使SWING Thread等待,直到它收到一个永远不会到来的notify(),因为t.notifyAll()只能通过同一个SWING线程到达(所以就像你要睡觉一样而你正在等待自己叫醒你...祝你好运)。

这是一个解决方案(不是最好的,因为它不关心同步):

  final  boolean [] pause = new boolean []{false};
  Runnable r = new Runnable()
{
     public void run()
     {
         while(true)
         {
             if(!pause[0])
             window1.paintImage();//fn to redraw an image
         }
     }
};

...

public void keyPressed(KeyEvent e)
    {
        if(e.getKeyCode() == KeyEvent.VK_P)
        {
            if(!pause[0])
            {
                pause[0] = true;
            } else
            {
                pause[0] = false;
            }
        }
    }