【问题标题】:Is there a quick way to close a thread before the main code continues?在主代码继续之前有没有快速关闭线程的方法?
【发布时间】:2019-05-31 20:28:48
【问题描述】:

我有一个学生正在为学校的期末项目制作西蒙游戏,我整天都在尝试解决她的问题。 她正在尝试创建游戏西蒙。该程序随机选择一系列颜色并通过将 4 个彩色按钮的颜色从常规颜色更改为白色几秒钟然后返回来突出显示这些颜色。 编程不是一次突出一种颜色为白色,而是使所有颜色同时显示为白色。所以用户不知道顺序。

我一直在查找运行多个线程的问题,并尝试使用 .join() 函数。但是,当使用它时,没有颜色会变白。

//突出显示当前在数组中的颜色


public void play() {

   //loop through the array and look at all the colours so far     
   for(int i=0; i<round;i++){

             //red is the position in the array
             if(colours[i]==1){

                  Thread sleep=new Thread(new Runnable(){
                     @Override
                     public void run(){
                         //change the colour of the red button to white
                         redButton.setBackground(Color.WHITE);
                         redButton.setOpaque(true);


                            //wait 
                            try {
                                Thread.currentThread().sleep(1000);
                                }
                             catch (InterruptedException e) {
                                e.printStackTrace();
                                }
                            //change the colour back
                        redButton.setBackground(Color.RED);
                         redButton.setOpaque(false);
                     }
                 });

                        sleep.start();


             }




             //yellow
             else if(colours[i]==2){
                 Thread sleep=new Thread(new Runnable(){
                     @Override
                     public void run(){
                         yellowButton.setBackground(Color.WHITE);
                         yellowButton.setOpaque(true);


                            try {
                                Thread.currentThread().sleep(1000);
                                }
                             catch (InterruptedException e) {
                                e.printStackTrace();
                                }
                         yellowButton.setBackground(Color.YELLOW); 
                        yellowButton.setOpaque(false);
                     }
                 });
                 sleep.start();




             }
             //green
             else if(colours[i]==3){
                 Thread sleep=new Thread(new Runnable(){
                     @Override
                     public void run(){
                         greenButton.setBackground(Color.WHITE);
                         greenButton.setOpaque(true);


                            try {
                                Thread.currentThread().sleep(1000);
                                }
                             catch (InterruptedException e) {
                                e.printStackTrace();
                                }
                         greenButton.setBackground(Color.GREEN); 
                        greenButton.setOpaque(false);


                     }
                 });
                 sleep.start();



             }
             //blue
             else if(colours[i]==4){
                 Thread sleep=new Thread(new Runnable(){
                     @Override
                     public void run(){
                         blueButton.setBackground(Color.WHITE);
                         blueButton.setOpaque(true);


                            try {
                                Thread.currentThread().sleep(1000);
                                }
                             catch (InterruptedException e) {
                                e.printStackTrace();
                                }
                         blueButton.setBackground(Color.CYAN); 
                         blueButton.setOpaque(false);


                     }
                 });
                 sleep.start();




             }  

   }

}

【问题讨论】:

  • 那些按钮,JButtons 来自 Swing?在那种情况下,我根本不会使用线程。我会使用javax.swing.Timer 来安排不同的屏幕颜色变化。

标签: java multithreading join


【解决方案1】:

那里的代码基本上是这样说的。

对于序列中的所有步骤,每个步骤都启动一个线程。
然后每个线程(所有线程都在彼此之后很快开始,而不是在前一个完成之前。)将背景设置为白色 1 秒钟然后返回。

通常您希望在后台更新 ui 以便您可以继续交互,但在这种情况下您正在播放序列并且不需要任何输入。如果需要在后台更新,则将整个循环放在一个线程中,您将希望在该循环的迭代之间休眠。否则只需在主线程中执行。一旦为用户播放完序列,它会将控制权传递回事件循环以等待按下。

延迟也应该是 .3s

【讨论】:

    【解决方案2】:

    虽然您想在 1 秒内更改每个按钮的颜色,但您的主线程太快并在那一秒内完成。这就是为什么所有灯光似乎都在同时变化的原因。

    简单的解决方案也是让外线程休眠一段时间,但这并不能保证线程的顺序。我建议使用java.util.concurrent.CountDownLatch 让外线程等待内线程完成。

        for (int i = 0; i < round; i++) {
            CountDownLatch countDownLatch = new CountDownLatch(1);
            // red is the position in the array
            if (colours[i] == 1) {
                Thread sleep = new Thread(new Worker(redButton, Color.RED, countDownLatch))
                sleep.start();
    
            }
    
            // yellow
            else if (colours[i] == 2) {
                Thread sleep = new Thread(new Worker(yellowButton, Color.YELLOW, countDownLatch))
                sleep.start();
    
            }
            // green
            else if (colours[i] == 3) {
                Thread sleep = new Thread(new Worker(greenButton, Color.GREEN, countDownLatch))
                sleep.start();
    
            }
            // blue
            else if (colours[i] == 4) {
                Thread sleep = new Thread(new Worker(blueButton, Color.CYAN, countDownLatch))
                sleep.start();
    
            }
            countDownLatch.await();
        }
    }
    
    class Worker implements Runnable {
        Button button;
        Color color;
        CountDownLatch countDownLatch;
    
        public Worker(Button button, Color color, CountDownLatch countDownLatch) {
            this.button = button;
            this.color = color;
            this.countDownLatch = countDownLatch;
        }
    
        @Override
        public void run() {
            button.setBackground(Color.WHITE);
            button.setOpaque(true);
    
            try {
                Thread.currentThread().sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            button.setBackground(color);
            button.setOpaque(false);
            countDownLatch.countDown();
    
        }
    }
    

    一旦灯光改变颜色 1 秒钟,您就可以使用 countDownLatch.countDown() 对闩锁进行倒计时,然后在外螺纹中使用 countDownLatch.await() 等待倒计时到零。

    【讨论】:

      猜你喜欢
      • 2011-06-20
      • 1970-01-01
      • 2019-07-22
      • 1970-01-01
      • 2014-04-14
      • 2021-05-06
      • 2015-04-09
      • 1970-01-01
      • 2016-11-04
      相关资源
      最近更新 更多