Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/397.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 同时中断多个线程_Java_Multithreading_Thread Safety_Interrupted Exception - Fatal编程技术网

Java 同时中断多个线程

Java 同时中断多个线程,java,multithreading,thread-safety,interrupted-exception,Java,Multithreading,Thread Safety,Interrupted Exception,我在一个框架上有3个线程,当我按下“退出”按钮时,我想停止当前正在运行的线程,然后用程序关闭框架。为此,我创建了一个数组,其中包含帧的所有线程,当按下“退出”按钮时,程序会在数组上迭代,如果有线程运行,我会中断它。我的方法的问题是程序只停止一个线程,而不是所有线程。因此,即使框架关闭,也会有2个线程在后台运行 这是我的节目: import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.even

我在一个框架上有3个线程,当我按下“退出”按钮时,我想停止当前正在运行的线程,然后用程序关闭框架。为此,我创建了一个数组,其中包含帧的所有线程,当按下“退出”按钮时,程序会在数组上迭代,如果有线程运行,我会中断它。我的方法的问题是程序只停止一个线程,而不是所有线程。因此,即使框架关闭,也会有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;
    }
}
导入java.awt.FlowLayout;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.lang.Thread.State;
导入javax.swing.JButton;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
公共类编程接口扩展了JFrame{
私人JButton stopThreadsAndExit;
私有计数器线程[]计数器线程数组=新计数器线程[3];
公共静态void main(字符串[]args){
新的编程接口();
}
公共程序接口(){
//TODO自动生成的构造函数存根
addCounterThreadsToArray();
在框架()上添加螺纹;
stopThreadsAndExit=新的JButton(“退出”);
addActionToExitButton();
添加(stopThreadsAndExit);
setFrameSettings();
}
私有void setFrameSettings(){
设置大小(400400);
setLayout(新的FlowLayout());
setVisible(真);
}
public void addThreadsOnTheFrame(){
用于(反向线程计数器:反向线程阵列){
添加(计数器);
}
}
public void addActionToExitButton(){
stopThreadsAndExit=新的JButton(“退出”);
stopThreadsAndExit.addActionListener(新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
//TODO自动生成的方法存根
新线程(newrunnable()){
@凌驾
公开募捐{
//TODO自动生成的方法存根
退出();
}
}).start();
}
});
}
公共无效出口(){
用于(反向线程计数器:反向线程阵列){
if(counter.isRunnable()){
counter.interruptThread();
}
}
处置();
}
私有void addCounterThreadsToArray(){
反螺纹阵列[0]=新反螺纹(“螺纹01”);
反螺纹阵列[1]=新反螺纹(“螺纹02”);
反螺纹阵列[2]=新反螺纹(“螺纹03”);
}
}
类计数器线程扩展了JPanel{
线程计数器;
私有字符串threadName;
私有JButton开始线程;
公共反螺纹(螺纹串){
this.threadName=threadString;
初始化计数器线程();
addActionToStartButton();
setLayout(新的FlowLayout());
添加(startThread);
}
public void addActionToStartButton(){
startThread=newjbutton(“Start”+threadName);
startThread.addActionListener(新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
//TODO自动生成的方法存根
counter.start();
}
});
}
私有void initializeCounterThread(){
计数器=新线程(新可运行(){
@凌驾
公开募捐{
//TODO自动生成的方法存根
试一试{
对于(int i=0;i<100000000;i++){
如果(Thread.currentThread().isInterrupted()){
抛出新的InterruptedException();
}
System.out.println(threadName+“生成的”+i);
}
}捕捉(中断异常e){
//TODO:处理异常
Thread.currentThread().interrupt();
}
}
});
}
public void interruptThread(){
计数器中断();
}
公共布尔值不可命名(){
返回计数器.getState()==State.RUNNABLE;
}
}

不要检查线程上的getState,您不必关心它当前是否正在运行。打电话就可以了


当您在一个线程上调用中断时,该线程只是在该实例上设置了一个标志。当线程执行某些操作(如等待或睡眠)时,或者当线程显式调用isInterrupted(您正在执行)时,会检查该标志。因此,您无需关心线程处于何种状态。

谢谢!成功了。你觉得代码怎么样?业务逻辑是否正确?我必须改进它吗?@ RuSU:您可以考虑使用ExtutoService。