首页 > 解决方案 > 如何重新启动流

问题描述

我有一个表格

public class MainFrame extends JFrame {
    private int colThread=0;
    MainThread mt=new MainThread("Поток - 1");

    public MainFrame()  
    {
        setSize(300,300);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel jp = new JPanel();
        JButton jb=new JButton("Запустить поток");
        jb.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                jb.setText("Перезапустить поток");
                colThread = colThread + 1;
                if (!mt.isInterrupted())
                {
                    mt.interrupt();
                }
                mt.start();             
            }           
        });
        jp.add(jb);
        add(jp);
    }
}

我有一个线程类:

public class MainThread extends Thread{
    private int summ;
    private String threadName;

    public MainThread(String threadName)
    {
        this.threadName = threadName;
    }   

    @Override
    public void run() {
        summ = 0;
        while(true)
        {
            summ = summ +1;
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println(this.threadName + " " + summ);
        }
    }
}

我有主要课程:

public class MainClass {
    public static void main(String[] args) {
        MainFrame mf = new MainFrame();
        mf.setVisible(true);
    }
}

问题是单击按钮时如何重新启动线程执行。以这种形式执行程序时,会出现错误,不过这是可以理解的,因为线程工作,不清楚为什么interrupt()不工作?

标签: javamultithreadingswing

解决方案


Thread.start() 的文档中

多次启动一个线程是不合法的。特别是,线程一旦完成执行就可能不会重新启动。

但是您可以创建 Runnable 的单个实现,并将其反复传递给 Thread 构造函数:

public class MainThread implements Runnable {

然后在您的 MainFrame 类中,执行以下操作:

public class MainFrame extends JFrame {
    private int colThread=0;
    private MainThread task = new MainThread("Поток - 1");
    private Thread mt = null;

    // ...

        public void actionPerformed(ActionEvent arg0) {
            jb.setText("Перезапустить поток");
            colThread = colThread + 1;
            if (mt != null && !mt.isInterrupted())
            {
                mt.interrupt();
            }

            mt = new Thread(task);
            mt.start();

请注意,线程主体负责在中断时干净地退出。中断应始终被视为停止您正在做的事情的请求:

    while(true)
    {
        summ = summ +1;
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            break;      // Someone wants this method to exit!
        }
        System.out.println(this.threadName + " " + summ);
    }

更好的方法是将while循环放在try/catch 中:

    try {
        while(true)
        {
            summ = summ +1;
            Thread.sleep(1000);
            System.out.println(this.threadName + " " + summ);
        }
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

这将使循环在中断时自动退出。


推荐阅读