同时中断多个线程
Interrupt multiple threads on the same time
我在框架上有 3 个线程,当我按下 "Exit" 按钮时,我想停止当前为 运行 的线程,然后用程序关闭框架。为此,我创建了一个数组,其中包含框架的所有线程,当按下按钮 "Exit" 时,程序将遍历该数组,如果有任何线程 运行,我会中断它。我的方法的问题是程序只停止了 1 个线程,而不是所有线程。所以,即使框架关闭,后台也会有2个线程运行。
这是我的程序:
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.Thread.State;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ProgramInterface extends JFrame {
private JButton stopThreadsAndExit;
private CounterThread[] counterThreadsArray = new CounterThread[3];
public static void main(String[] args) {
new ProgramInterface();
}
public ProgramInterface() {
// TODO Auto-generated constructor stub
addCounterThreadsToArray();
addThreadsOnTheFrame();
stopThreadsAndExit = new JButton("Exit");
addActionToExitButton();
add(stopThreadsAndExit);
setFrameSettings();
}
private void setFrameSettings() {
setSize(400, 400);
setLayout(new FlowLayout());
setVisible(true);
}
public void addThreadsOnTheFrame() {
for (CounterThread counter : counterThreadsArray) {
add(counter);
}
}
public void addActionToExitButton() {
stopThreadsAndExit = new JButton("Exit");
stopThreadsAndExit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
exit();
}
}).start();
}
});
}
public void exit() {
for (CounterThread counter : counterThreadsArray) {
if (counter.isRunnable()) {
counter.interruptThread();
}
}
dispose();
}
private void addCounterThreadsToArray() {
counterThreadsArray[0] = new CounterThread("Thread 01");
counterThreadsArray[1] = new CounterThread("Thread 02");
counterThreadsArray[2] = new CounterThread("Thread 03");
}
}
class CounterThread extends JPanel {
Thread counter;
private String threadName;
private JButton startThread;
public CounterThread(String threadString) {
this.threadName = threadString;
initializesCounterThread();
addActionToStartButton();
setLayout(new FlowLayout());
add(startThread);
}
public void addActionToStartButton() {
startThread = new JButton("Start " + threadName);
startThread.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
counter.start();
}
});
}
private void initializesCounterThread() {
counter = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
for (int i = 0; i < 1000000000; i++) {
if (Thread.currentThread().isInterrupted()) {
throw new InterruptedException();
}
System.out.println(threadName + " generated " + i);
}
} catch (InterruptedException e) {
// TODO: handle exception
Thread.currentThread().interrupt();
}
}
});
}
public void interruptThread() {
counter.interrupt();
}
public boolean isRunnable() {
return counter.getState() == State.RUNNABLE;
}
}
不要检查线程上的 getState,您不必关心它当前是否 运行。只需对其调用中断即可。
当您在一个线程上调用中断时,该线程只是在该实例上设置了一个标志。当线程做某些事情时,比如等待或睡眠,或者当线程显式调用 isInterrupted(你正在做的)时,该标志会被检查。所以你不需要关心线程处于什么状态。
我在框架上有 3 个线程,当我按下 "Exit" 按钮时,我想停止当前为 运行 的线程,然后用程序关闭框架。为此,我创建了一个数组,其中包含框架的所有线程,当按下按钮 "Exit" 时,程序将遍历该数组,如果有任何线程 运行,我会中断它。我的方法的问题是程序只停止了 1 个线程,而不是所有线程。所以,即使框架关闭,后台也会有2个线程运行。
这是我的程序:
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.Thread.State;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ProgramInterface extends JFrame {
private JButton stopThreadsAndExit;
private CounterThread[] counterThreadsArray = new CounterThread[3];
public static void main(String[] args) {
new ProgramInterface();
}
public ProgramInterface() {
// TODO Auto-generated constructor stub
addCounterThreadsToArray();
addThreadsOnTheFrame();
stopThreadsAndExit = new JButton("Exit");
addActionToExitButton();
add(stopThreadsAndExit);
setFrameSettings();
}
private void setFrameSettings() {
setSize(400, 400);
setLayout(new FlowLayout());
setVisible(true);
}
public void addThreadsOnTheFrame() {
for (CounterThread counter : counterThreadsArray) {
add(counter);
}
}
public void addActionToExitButton() {
stopThreadsAndExit = new JButton("Exit");
stopThreadsAndExit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
exit();
}
}).start();
}
});
}
public void exit() {
for (CounterThread counter : counterThreadsArray) {
if (counter.isRunnable()) {
counter.interruptThread();
}
}
dispose();
}
private void addCounterThreadsToArray() {
counterThreadsArray[0] = new CounterThread("Thread 01");
counterThreadsArray[1] = new CounterThread("Thread 02");
counterThreadsArray[2] = new CounterThread("Thread 03");
}
}
class CounterThread extends JPanel {
Thread counter;
private String threadName;
private JButton startThread;
public CounterThread(String threadString) {
this.threadName = threadString;
initializesCounterThread();
addActionToStartButton();
setLayout(new FlowLayout());
add(startThread);
}
public void addActionToStartButton() {
startThread = new JButton("Start " + threadName);
startThread.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
counter.start();
}
});
}
private void initializesCounterThread() {
counter = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
for (int i = 0; i < 1000000000; i++) {
if (Thread.currentThread().isInterrupted()) {
throw new InterruptedException();
}
System.out.println(threadName + " generated " + i);
}
} catch (InterruptedException e) {
// TODO: handle exception
Thread.currentThread().interrupt();
}
}
});
}
public void interruptThread() {
counter.interrupt();
}
public boolean isRunnable() {
return counter.getState() == State.RUNNABLE;
}
}
不要检查线程上的 getState,您不必关心它当前是否 运行。只需对其调用中断即可。
当您在一个线程上调用中断时,该线程只是在该实例上设置了一个标志。当线程做某些事情时,比如等待或睡眠,或者当线程显式调用 isInterrupted(你正在做的)时,该标志会被检查。所以你不需要关心线程处于什么状态。