使用外部事件退出 while 循环

Posted

技术标签:

【中文标题】使用外部事件退出 while 循环【英文标题】:Quit while loop with external event 【发布时间】:2014-04-03 08:25:39 【问题描述】:

我有一个这样的循环:

while (!exit)

read/write on file


我的框架上有一个按钮,他的动作改变了“退出”的值,即循环的退出条件。

我的问题,我卡在我的循环中,我无法点击我的按钮,因为我认为程序一直在循环中。

有人告诉我用“轮询”查看线程,但我不明白如何集成到我的循环中?

编辑:

我如何称呼线程:

case "Mode Measure": 
    JOptionPane.showMessageDialog(null,"Radar in Measure Mode : ON ");
    System.out.println("READ Mode : ON ");
    JB_MeasurMode.setVisible(true);

    JB_MeasurMode.addActionListener(new ActionListener()
    public void actionPerformed(ActionEvent arg0) 
        sortie = true;
              
    );

    SwingUtilities.invokeLater(new Runnable() 
    public void run() 
        CommPortIdentifier portId = null;
        try 
            portId = CommPortIdentifier.getPortIdentifier(ChoixPortCom);
            serialPort = (SerialPort) portId.open("Main Frame", 5000);
            System.out.println("serialPort ouvert");
            outputStream = serialPort.getOutputStream();
            inputStream = serialPort.getInputStream();
            serialPort.setRTS(false);
            serialPort.setInputBufferSize(8192);
            serialPort.setOutputBufferSize(8192);
            serialPort.setSerialPortParams(115400,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
            serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_XONXOFF_IN |SerialPort.FLOWCONTROL_XONXOFF_OUT);
            catch (NoSuchPortException e1) 
                // TODO Auto-generated catch block
                    e1.printStackTrace();
             catch (PortInUseException e) 
                // TODO Auto-generated catch block
                e.printStackTrace();
             catch (IOException e) 
                // TODO Auto-generated catch block
                e.printStackTrace();
             catch (UnsupportedCommOperationException e) 
                // TODO Auto-generated catch block
                e.printStackTrace();
            
    System.out.println("Dans le while");
    while(sortie == false) 
            int i = 0;
        int availableBytes = 0;
        try 
            int read = 0;
            availableBytes = inputStream.available();
            if (availableBytes > 0) 
                String tradV3 = null;
                System.out.println("je suis dans le availableBytes > 0 du while -- read = "+read);
                read = read + availableBytes;
                int raw = inputStream.read(readBuffer, read-availableBytes, availableBytes);
                traduction = new String(readBuffer, read-availableBytes, raw);          
                    System.out.println("2=>" + traduction);
                tradV3 = tradV3 + traduction;   // bytes -> String
            

            if (read == 19)

                System.out.println("une donnee de 19 char lue -- read = "+read);
                System.out.println("Non-Traité :"+Arrays.toString(readBuffer));
                int[] tab_int2 = new int[19];
                tab_int2 = Fonction.Get_Msg_19(readBuffer);
                String Msg_affiche2 = Arrays.toString(tab_int2);
                System.out.println("Traité : "+Msg_affiche2);
                Measure t = new Measure();
                t.GetMeasure(tab_int2);
                Tab_Measure[i] = t;
                i++;
            
             catch (IOException e) 
                System.out.println("Problem avec le try !!!");
            
        
        System.out.println("Sortie du while");
                
    );
break;

【问题讨论】:

他是对的。您需要第二个线程来更改exit 的值。 另外,while (!exit) 就足够了 (small 'w') 好的,但是我把它放在哪里以及如何使用它。你有好的教程吗? @D3fman While 在 Java 中不存在。这是while。来吧,只是谷歌它! @Christian:你告诉我这个是因为大写吗? ps:我编辑了。如果我在这里问,也许我在来这里之前搜索过:D 【参考方案1】:

因为读/写操作可能是一个非常长的任务,您应该在不同的线程中执行它,以免阻塞主 UI 线程。

SwingWorker 类可能会有所帮助,因为它是为处理此类长时间任务而创建的。 看看这里:http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html

如果你使用 SwingWorker 而不是你的标志,当有人按下你的按钮时,你应该调用 SwingWorker 的取消方法。

【讨论】:

因为在不更改标志的情况下不可能完成循环,所以这并不重要,但我更普遍地认为应该如何处理这样的任务。无论如何,他必须创建另一个线程,但将 I/O 操作移至 SwingWorker 类是个好主意。【参考方案2】:

您可能正在 GUI 线程中运行循环,该线程还负责处理按钮单击。当它卡在 while 循环中时,它不能用于更改变量“exit”的值。在单独的线程中进行读/写,在 Swing 中有一个方便的类:

SwingUtilities.invokeLater(new Runnable() 
            @Override
            public void run() 
// IO stuff
            
        );

【讨论】:

你能快速检查一下我的代码吗,告诉我是否正确调用它,如果没有,我应该如何调用它。使用此代码,按钮仍然没有响应。 Sorry SwingUtilities'方法invokeLater实际上也会导致代码在GUI线程中执行,实际上你需要使用SwingWorker创建一个新线程并且不在GUI线程中执行代码***.com/questions/11255925/… 顺便说一句,您可以使用 docs.oracle.com/javase/7/docs/api/javax/swing/… 方法检查您是否在 GUI 线程中

以上是关于使用外部事件退出 while 循环的主要内容,如果未能解决你的问题,请参考以下文章

退出循环break,在whilefordo...while循环中使用break语句退出当前循环,直接执行后面的代码。

为啥while循环不退出?

如何在 Java 中退出 while 循环?

为啥while循环有时会在满足退出条件之前退出?

在 Python 3.4 中按 Enter 退出 While 循环

PHP过早退出while循环