我遇到了一些异常,我需要知道程序何时关闭,因为我需要关闭套接字。
我有默认的public static main方法,我不断重复一个动作和一个Thread类。
private static Thread thread;
public static boolean isRunning = true;
public static void main(String[] args){
thread = new Thread(new ThreadListenServer());
thread.start();
Timer timer = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run(){
// some action
}
}
timer.scheduleAtFixedRate(task, 0, 10000);
isRunning = false;
}
在后台运行的线程类:
public class ThreadListenServer implements Runnable{
private DatagramSocket socket;
public ThreadListenServer() throws SocketException{
socket = new DatagramSocket(6655);
}
@Override
public void run() {
while(MainProgram.isRunning){
// some action
}
socket.close();
}
}
我不知道为什么,但是isRunning
它变得虚假,但它不应该。如果主程序关闭,我该如何关闭套接字? (这是因为即使程序关闭,线程仍然在后台运行)。
我正在考虑在主类中创建套接字,然后将套接字对象作为参数传递给ThreadClass,如果程序关闭,我也应该关闭套接字。
答案 0 :(得分:4)
使用:
thread.setDaemon(true);
这将关闭线程。它告诉JVM它是一个后台线程,所以它会在退出时关闭。
答案 1 :(得分:2)
我假设你有一个类型的MainFrogram运行的JFrame。你有2个选择
1:设置Jframe在关闭时关闭所有线程。
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
2:添加一个窗口监听器并手动关闭你的线程(也许你必须在关闭它之前通过套接字发送一些信息)
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
// send your socket its close message and shut everything down
System.exit(0);
}
});
答案 2 :(得分:1)
有些事情会浮现在脑海中。
setDaemon(true)
在启动之前将线程设置为守护程序线程。这将允许JVM自动终止线程...... isRunning
应标记为volatile
,或者您应使用AtomicBoolean
代替答案 3 :(得分:1)
要在程序退出干净地时停止所有线程,您需要为每个启动的线程定义终止策略。这通常使用Interrupts
完成,ExecutorService.shutdownNow()
方法向每个正在运行的线程发送一个中断。
清洁终止政策包括两部分:
通过调用Thread.interrupt()
方法可以中断Java中的线程。线程可以通过调用Thread.isInterrupted()
方法来检查中断。一个好的线程必须定期检查中断,例如作为循环条件并检查InterruptedExceptions
的阻塞函数。
值得注意的是,Java中的Socket
无法中断。例如,如果某个线程在Socket.accept()
上被阻止,则当线程中断时它不会抛出InterruptedException
。在这种情况下,您需要定义一个公共方法,通过调用Socket.close()
来强制阻塞函数抛出异常(我猜SocketException
)来关闭底层套接字。