繁体   English   中英

为什么程序没有终止?

[英]Why is program not terminating?

我是使用Timer类的新手,因此在将其合并到我的项目之前尝试使用它。 我想知道为什么这个程序在计数达到5时不会终止。即使不满足while循环的条件,程序也会继续运行。

package Timer;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;

public class demo {

    private static int count;


    public static void main(String[] args) {
        ActionListener executeThis = new ActionListener(){


            @Override
            public void actionPerformed(ActionEvent arg0) {
                // TODO Auto-generated method stub
                System.out.println("Hello");
                count++;

            }

        };

        Timer timer = new Timer(500, executeThis);
        timer.setInitialDelay(1000);
        timer.start();

        while(count < 5){

        }
    }

}

你应该添加:

timer.stop();

为了停止计时器调度。

另一个问题是在多线程环境中使用非原子变量。 您可以使用AtomicInteger。

如果count == 5,您可以在actionPerformed方法中执行此操作。

用于停止计时器

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.atomic.AtomicInteger;


public class Test1 {
    private static AtomicInteger count = new AtomicInteger(0);

    public static void main(String[] args) {
        ActionListener executeThis = new ActionListener(){


            @Override
            public void actionPerformed(ActionEvent arg0) {
                // TODO Auto-generated method stub
                System.out.println("Hello");
                count.getAndIncrement();

            }

        };

        Timer timer = new Timer(500, executeThis);
        timer.setInitialDelay(1000);
        timer.start();

        while(count.get() < 5){

        }
        timer.stop();

    }
}

但我认为这将是正确的方法

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * User: Romeo Sheshi 
 * Date: 21/03/16
 * Time: 12:12
 */
public class Test {
    private static AtomicInteger count = new AtomicInteger(0);
    private static Timer timer;
    public static void main(String[] args) {


        ActionListener executeThis = new ActionListener(){


            @Override
            public void actionPerformed(ActionEvent arg0) {
                // TODO Auto-generated method stub
                System.out.println("Hello");

                if( count.incrementAndGet()==5){
                   stopTimer();
                }

            }

        };
        timer = new Timer(500, executeThis);
        timer.setInitialDelay(1000);
        startTimer();

        while ( count.get()<5){}

    }

    public static void startTimer(){
        timer.start();
    }

    public static void stopTimer(){
        timer.stop();
    }
}

有两个问题:

  • 计时器在未停止时保持运行。
  • 静态计数变量不会在线程之间同步。

检查Gray的这个解释,了解线程之间的同步: java中的静态变量和多线程他解释说每个线程都有自己的静态变量副本。 为了避免这种情况,声明变量volatile。

对于像这个例子这样的简单测试,只需要一个volatile变量。 对于需要在线程之间进行实时同步的紧急情况,请使用AtomicInteger。

private static volatile int count;

确保使用timer.stop()停止计时器。 在循环中添加Thread.sleep并没有错,这可以保护CPU资源并允许非易失性变量的线程同步。

while (count < 5) {
  Thread.sleep(10);
}    
timer.stop();

你可以在这里阅读更多关于volatile变量和AtomicInteger 之间的区别:atomic / volatile / synchronized之间有什么区别?

这是Romeo Sheshi的支持答案

此代码已经过测试:

  • 视窗; Java 1.7.0_75使用Netbeans 8和命令行
  • MacOS 10.11.3; Java 1.8.0_20使用Netbeans 8和终端

在这两种情况下,计划在计数达到5后终止

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.atomic.AtomicInteger;
import javax.swing.Timer;

public class Test {

    private static AtomicInteger count = new AtomicInteger(0);

    public static void main(String[] args) {
        ActionListener executeThis = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                // TODO Auto-generated method stub
                System.out.println("Hello");
                count.getAndIncrement();
                System.out.println(count);
            }

        };

        Timer timer = new Timer(500, executeThis);
        timer.setInitialDelay(1000);
        timer.start();

        while (count.get() < 5) {
        }
        System.out.println("On the outside...");
        timer.stop();
    }

}

最好和最简单的方法是 -

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;

public class demo {

    private static int count;


    public static void main(String[] args) {
        ActionListener executeThis = new ActionListener(){


            @Override
            public void actionPerformed(ActionEvent arg0) {
                // TODO Auto-generated method stub
                System.out.println("Hello");
                count++;
                if(count==5){
                    System.exit(0);                 
                }
            }

        };

        Timer timer = new Timer(500, executeThis);
        timer.setInitialDelay(1000);
        timer.start();

        while(count < 5){

        }
    }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM