【问题标题】:Thread isn't pausing when pause button is clicked单击暂停按钮时线程不会暂停
【发布时间】:2013-04-03 00:03:30
【问题描述】:

我试图在用户单击暂停按钮时暂停弹跳球动画,并在他们单击恢复时恢复它。问题是当我单击暂停按钮时,它应该将suspendRequested 设置为true,因此它进入if 语句并运行while 语句,这会导致线程等待,从而停止球的动画。然后,当用户单击 resume 时,它​​应该将其设置回 false ,这会将其从 while 循环中中断并继续动画。这不会发生,为什么它没有跳出循环?

class BallRunnable implements Runnable
{
   private Lock suspendLock = new ReentrantLock();
   private Condition suspendCondition = suspendLock.newCondition();
   private volatile boolean suspendRequested = false;
   private boolean isBouncing = true;
   private Ball ball;
   private Component component;
   public static final int STEPS = 1000;
   public static final int DELAY = 100;

   /**
    * Constructs the runnable.
    * @param aBall the ball to bounce
    * @param aComponent the component in which the ball bounces
    */
   public BallRunnable()
   {
   }
   public BallRunnable(Ball aBall, Component aComponent)
   {
      ball = aBall;
      component = aComponent;
   }

   public void run()
   {
      while(isBouncing())
      {
          try
          {
                ball.move(component.getBounds());
                component.repaint();
                Thread.sleep(DELAY);
                String name = Thread.currentThread().getName();
                System.out.println("Ball is bouncing " + name);
                if(suspendRequested)
                {
                    suspendLock.lock();
                    System.out.println("Locking thread");
                    try
                    {
                        while(suspendRequested)
                        {
                            System.out.println("About to await");
                            suspendCondition.await();
                        }
                    }
                    catch (InterruptedException e)
                    {
                    }
                    finally
                    {
                     suspendLock.unlock();
                     System.out.println("Unlocked " + name);
                    }
                }
          }
          catch (InterruptedException e)
          {
          }

        }
    }

    public boolean isBouncing()
    {
        if(isBouncing)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    public void setBouncing(boolean b)
    {
        isBouncing = b;
    }

   public void requestSuspend()
   {
       suspendRequested = true;
   }

   public void requestResume()
   {
       suspendRequested = false;
       suspendLock.lock();
       try
       {
           suspendCondition.signalAll();
       }
       finally
       {
           suspendLock.unlock();
       }
   }

}

这里应该在单击按钮时暂停和恢复线程,但不会将它们打断循环。如果使它看起来的布尔值设置为 true,然后用户按下暂停将其更改为 false,它不应该将其从循环中中断吗?

class BounceFrame extends JFrame
{
   BallRunnable br = new BallRunnable();
   private BallComponent comp;

   /**
    * Constructs the frame with the component for showing the bouncing ball and Start and Close
    * buttons
    */
   public BounceFrame()
   {
      comp = new BallComponent();
      add(comp, BorderLayout.CENTER);
      JPanel buttonPanel = new JPanel();
      addButton(buttonPanel, "Start", new ActionListener()
         {
            public void actionPerformed(ActionEvent event)
            {
               addBall();
               //Don't let user click again
               System.out.println("Clicked start");
            }
         });

    addButton(buttonPanel, "Pause", new ActionListener()
    {
        public void actionPerformed(ActionEvent event)
        {

            System.out.println("Clicked Paused");
            br.setBouncing(false);
            System.out.println("Clicked Paused STOP BOUNCinG");
            br.requestSuspend();
            String name = Thread.currentThread().getName();
            System.out.println("Clicked Paused REQUEST SUSPEND " + name);
        }
    });

    addButton(buttonPanel, "Resume", new ActionListener()
        {
            public void actionPerformed(ActionEvent event)
            {
                System.out.println("Clicked Resume");
                br.setBouncing(true);
                br.requestResume();
            }
    });

      add(buttonPanel, BorderLayout.SOUTH);
      pack();
   }

这是家庭作业,所以我不是在寻找解决方案,但是当点击暂停按钮时,我没有看到关于跳出循环的什么?

【问题讨论】:

  • 我担心isBouncing可能会在suspendRequested之前被处理,这意味着run方法将退出,无法恢复
  • 我运行你的代码没有问题。我确实将suspendRequested 的检查移到了Thread.sleep 上方,但我看不出有什么不同,似乎问题可能出在其他地方

标签: java multithreading button


【解决方案1】:

所以实际上我使用了计时器对象,当您按下按钮时计时器将启动,如果您再次单击它将停止,您需要为您的弹跳球创建一个计时器类。其实我用的是鼠标按下动作执行的方法,但是是一样的

if (myTimer.isRunning())
    {
     myTimer.stop();
    }
    else
    {
     myTimer.start();
    }
    }
    });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多