为什么我的代码中的线程没有中断?

时间:2015-10-28 07:38:32

标签: java multithreading

我是Java的新手,实在无法弄清楚某些功能如中断是如何工作的。我在这里读过javadocs和之前的答案,所以我想我应该把代码置于while(!interrupt)循环中,如果它接收到中断状态,它应该关闭。我有2个按钮 - 启动和停止以及另一个类中的线程。线程的目的是读取条形码 - 一切正常,我得到所有异常的错误消息,但 Thread.currentThread()。interrupt(); 永远不会工作。同样适用于 t.interrupt() - t是线程类的实例。我做错了什么?

按钮:

Thread t = new Serverside();
//start server button
btnStartServer.addActionListener(event ->
{
btnStartServer.setEnabled(false);
btnStopServer.setEnabled(true);
connectButtonPressed = true;
try {
t.start();
}
catch (IllegalThreadStateException e)
{
t.interrupt();
JOptionPane.showMessageDialog(contentPane, "Error, thread already running.");
}
});
//Stop server button
btnStopServer.addActionListener(event ->
{
t.interrupt();
statusMsg.setText("trying to close connection");
});

带线程的类:

    class Serverside extends Thread
{
public void run()
{
    try {
    while(!Serverside.currentThread().interrupted())
    {

            try {
                server = new ServerSocket(Main.sock);
            } catch (IOException e) {
                JOptionPane.showMessageDialog(null, "Порт занят: " + Main.sock);
                //
                Serverside.currentThread().interrupt();
            }
            try {
                if (connectButtonPressed) {
                    Main.statusMsg.setText("ожидание подключения на порт " + Main.sock);
                    Main.client = server.accept();
                    Main.btnGetPhoto.setEnabled(true);
                    Main.isconnected = true;
                    Main.statusMsg.setText("соединение установлено");
                    //очистка экрана терминала
                    //Main.client.getOutputStream().write("\u001B[2J".getBytes());
                    //Main.client.getOutputStream().flush();
                }
                else
                {
                    JOptionPane.showMessageDialog(null, "Не нажата кнопка connect");
                    //
                    Thread.currentThread().interrupt();
                }
                if (!Main.isconnected)
                {
                    JOptionPane.showMessageDialog(null, "Нет соединения с клиентом");
                    //
                    Thread.currentThread().interrupt();
                }
                while (Main.isconnected) {
                    BufferedReader br = new BufferedReader(new InputStreamReader(Main.client.getInputStream()));
                    Main.line = br.readLine();
                    if (!Serverside.currentThread().interrupted())
                {
                    if (Main.line != null) {
                        try {
                            //Заменить строку ниже на динамически выбираемое имя файла
                            Main.myPicture = ImageIO.read(new File("P:/LM935230105CN.jpg"));
                            BufferedImage thumbnail = new BufferedImage(612, 512, BufferedImage.TYPE_INT_RGB);
                            Graphics2D g = thumbnail.createGraphics();
                            g.drawImage(Main.myPicture, 0, 0, 612, 512, null);
                            g.dispose();
                            Main.myIcon = new ImageIcon(thumbnail);
                            Main.picLabel.setIcon(Main.myIcon);
                        } catch (IOException ex) {
                            ex.printStackTrace();
                            JOptionPane.showMessageDialog(null, "Файл не найден!");
                        }
                        //Распознавание штрих-кода
                        Pattern pattern = Pattern.compile("[A-Za-z]{2}[0-9]{9}[A-Za-z]{2}");
                        Matcher matcher = pattern.matcher(Main.line);
                        if (matcher.find()) {
                            Main.barCodeMsg.setText(matcher.group());
                            Main.barCodeString = (matcher.group());
                            Main.barCodeStringArray = Main.barCodeString.split("");
                            final int[] ints = new int[9];

                            for (int i = 0; i < 9; i++) {
                                try {
                                    ints[i] = Integer.parseInt(Main.barCodeStringArray[i + 2]);
                                } catch (NumberFormatException e) {
                                    e.printStackTrace();
                                }
                            }
//код проверки контрольной суммы
                            int checksum = ints[8];
                            int temp;
                            temp = 11 - (ints[0] * 8 + ints[1] * 6 + ints[2] * 4 + ints[3] * 2 + ints[4] * 3 + ints[5] * 5 + ints[6] * 9 + ints[7] * 7) % 11;
                            if (temp == 10) {
                                temp = 0;
                            }
                            if (temp == 11) {
                                temp = 5;
                            }
                            if (temp == checksum) {
                                Main.statusMsg.setText("штрих-код обнаружен, контрольная сумма совпадает");
                            } else {
                                Main.statusMsg.setText("<html><font color='red'>штрих-код обнаружен, контрольная сумма не совпадает</font></html>");
                            }
                        } else {
                            //Строка принята, но штрих-код не распознан
                            Main.statusMsg.setText("данные не содержат штрих-кода");
                            barCodeString = "";
                        }
                    }
                    else {
                        //Строка не содержит данных
                        Main.picLabel.setIcon(null);
                    }
                }
                    else {
                        //blah-blah-blah
                        JOptionPane.showMessageDialog(null, "Поток прерван.");
                        break;
                    }
                }
            } catch (IOException e) {
                //
                Serverside.currentThread().interrupt();
                JOptionPane.showMessageDialog(null, "Ошибка соединения.");
                e.printStackTrace();
            } catch (NullPointerException e1) {
                JOptionPane.showMessageDialog(null, "Ошибка открытия порта");
                //
                Serverside.currentThread().interrupt();
                e1.printStackTrace();
            }
        }

    }
    finally
    {
        try
        {
            server.close();
            JOptionPane.showMessageDialog(null, "Порт" + sock + " закрыт");
        }
        catch (IOException e)
        {
            JOptionPane.showMessageDialog(null, "Ошибка закрытия порта");
            e.printStackTrace();
            //
            Serverside.currentThread().interrupt();
        }
    }
}
}

1 个答案:

答案 0 :(得分:0)

我认为这可能就是重点:

while (Main.isconnected) {

在内部检查是否存在中断状态,但如果是这样,则不要离开while循环。尝试在此处添加另一张支票。

while (Main.isconnected && !Serverside.currentThread().interrupted() {

另请注意:

  

此方法清除线程的中断状态。

所以我认为你应该使用isInterrupted()代替interrupted()

作为旁注,您还可以通过引入被调用的方法而不是一个long run()方法来“清理”代码。这有助于保持概述并调试部分代码中的缺陷。但如果这样可以,那就先“让它运行”......:)