这是关闭线程的好方法吗?

Rom*_*man -1 java multithreading interrupt

我有一个简短的问题版本:

  1. 我开始这样一个线程:counter.start();,counter一个线程在哪里.
  2. 当我想要停止线程时,我这样做: counter.interrupt()
  3. 在我的帖子中,我会定期进行检查:Thread.interrupted().如果它从线程中给出了truereturn,那么它就会停止.

如果需要,这里有一些细节:

如果您需要更多细节,他们就在这里.从发明调度线程我以这种方式启动一个反线程:

public static void start() {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            showGUI();
            counter.start();
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

线程的定义如下:

public static Thread counter = new Thread() {
    public void run() {
        for (int i=4; i>0; i=i-1) {
            updateGUI(i,label);
            try {Thread.sleep(1000);} catch(InterruptedException e) {};
        }
            // The time for the partner selection is over.
        SwingUtilities.invokeLater(new Runnable() {
                public void run() {    
                frame.remove(partnerSelectionPanel);
                frame.add(selectionFinishedPanel);
                frame.invalidate();
                frame.validate();
            }
        });
    }
};
Run Code Online (Sandbox Code Playgroud)

该线程在"第一个"窗口中执行倒计时(它显示主页很长时间).如果时间限制结束,则线程关闭"第一个"窗口并生成一个新窗口.我想用以下方式修改我的线程:

public static Thread counter = new Thread() {
    public void run() {
        for (int i=4; i>0; i=i-1) {
            if (!Thread.interrupted()) {
                updateGUI(i,label);
            } else {
                return;
            }
            try {Thread.sleep(1000);} catch(InterruptedException e) {};
        }
        // The time for the partner selection is over.
        if (!Thread.interrupted()) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {    
                frame.remove(partnerSelectionPanel);
                frame.add(selectionFinishedPanel);
                frame.invalidate();
                frame.validate();
            }
        });
        } else {
            return;
        } 
    }
};
Run Code Online (Sandbox Code Playgroud)

添加:

由于某些原因,它不起作用.我有一个中断线程的方法:

public static void partnerSelected() {
    System.out.println("The button is pressed!!!!");
    counter.interrupt();
}
Run Code Online (Sandbox Code Playgroud)

按下按钮时激活此方法.当我按下按钮时,我在终端中看到相应的输出(所以这个方法被激活,它会做一些事情).但由于某些原因,它不会中断线程.这是线程的代码:

public static Thread counter = new Thread() {
    public void run() {
        for (int i=40; i>0; i=i-1) {
                if (Thread.interrupted()) {
                    System.out.println("Helloo!!!!!!!!!!!!!!!");
                    return;
                }
            updateGUI(i,label); 
            try {Thread.sleep(1000);} catch(InterruptedException e) {};
        }
            // The time for the partner selection is over.
            if (Thread.interrupted()) {
                System.out.println("Helloo!!!!!!!!!!!!!!!");
                return;
            }
        SwingUtilities.invokeLater(new Runnable() {
                public void run() {    
                frame.remove(partnerSelectionPanel);
                frame.add(selectionFinishedPanel);
                frame.invalidate();
                frame.validate();
            }
        });
    }
};
Run Code Online (Sandbox Code Playgroud)

PS我没看到"你好!!!!!!!!!!!!!" 在终端......

Chr*_*ung 5

非常接近正确的想法.但是,catch (InterruptedException)你应该有:

Thread.currentThread().interrupt();
Run Code Online (Sandbox Code Playgroud)

这样中断的状态再次开始,并且不会在第二个块中执行操作.


编辑以使我的观点更清楚(因为OP的编辑似乎错过了我的初始点:-P):你应该像这样编写你的代码:

try {
    for (int = 40; i > 0; --i) {
        updateGUI(i, label);
        Thread.sleep(1000);
    }
} catch (InterruptedException e) {
    Thread.currentThread().interrupt();  // <-- THIS LINE IS IMPORTANT
}
Run Code Online (Sandbox Code Playgroud)

第二次编辑以解释中断的作用.:-)

当您调用时thread.interrupt(),将设置该线程的中断标志.那面旗帜本身没有做任何事情; 它只是一个变量.这是因为中断支持称为"协作线程管理"的东西,其中线程的运行代码决定在中断时要做什么(而不是被迫当场退出).

JDK中内置的一些函数,如Thread.sleepObject.wait,或者Lock.lockInterruptibly,将检查标志,如果已设置,那么它将InterruptedException在清除标志后抛出.

因此,如果您正在调用其中一个函数,则无需手动检查中断的标志.但是如果你不是,例如,如果你正在进行密集处理而不是等待什么,那么你应该定期检查标志.

有两种方法可以检查标志:

  1. interrupted()
  2. isInterrupted()

第一个清除中断的旗帜; 第二个没有.您必须确定哪个版本对您的应用程序逻辑"更正确".