如何保证跨多个线程的连续执行?

时间:2014-08-19 16:24:01

标签: java multithreading swing

我正在编写一个应用程序,它提供了一个用户友好的GUI替代方案来替换当前用户与远程设备通信的CLI。该应用程序将发送和接收所有CLI I / O,并将其转换为易于理解的用户语言。

由于应用程序和远程设备之间(几乎)在执行期间始终存在开放的SSH连接,因此后台Thread正在处理远程端的InputStream并对其进行缓存以便我的应用程序可以使用它。

我遇到的问题是,当我调用缓存数据时,它始终位于应该存在的位置,然后显示为这样。

后台线程类

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;


public class ASAOutputStreamReader implements Runnable {

    public volatile boolean stopNow;
    private InputStream in;
    public volatile String opString;
    public volatile List<String> cachedOut = new ArrayList<String>();


    ASAOutputStreamReader(InputStream in) {

        this.in = in;

    }

    @Override
    public void run() {

        Scanner scan = new Scanner(in);
        while (true) {

            scan.useDelimiter("\r");
            opString = scan.next();
            System.out.println(opString);
            // Add processed output to cache
            cachedOut.add(opString);
            if (stopNow) {
                scan.close();
                break;
            }
        }//end while

    }
    /* getNAT() - List<String>
     * Method to return the cached strings
     * from the ASA console, up to the point
     * that the command was submitted
     * NOTE: THIS WILL RETURN IN REVERSE ORDER
     * But does not affect functionality
     */

    public synchronized List<String> getNAT() {
        List<String> str = new ArrayList<String>();
        if (cachedOut.isEmpty() == false) {
            for (int i = cachedOut.size()-1; i >= 0; i--) {
                if (cachedOut.get(i).contains("show run static")) {
                    break;
                }
                str.add(cachedOut.get(i));
            }
        }
        return str;
    }
}

UI按钮&amp;方法

send_btn.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    // Defined separately to ensure Thread safety
                    updateNAT(listNATs, ip_tf.getText());
                }
            });

private void updateNAT(final JTextArea jta, final String host) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                ACL1.sendCmd("show run static | include " + host + "\r");
                String str = "";
                for (String s : ACL1.asaOSMonitor.getNAT()) {
                    str = str.concat(s).concat("\n");
                }
                jta.setText(str);
            }
        });
    }

我如何保证我的数据缓存最新&#34;最新&#34;在调用之前更新UI以将其显示给用户?

1 个答案:

答案 0 :(得分:-1)

信号量或任何其他并发同步机制(例如,C ++ for Win32应用程序中的Critical_Sections)。您使用信号量进入线程,其中每个线程抓取一个特定的信号量并递减它,同时递增其他信号量。也就是说; 线程A抓取信号量A并递减(&lt; 0)信号量A并递增信号量B(设置一个标志状态以表示它已为其他线程做好准备) 线程B抓取信号量B并递减它,同时递增信号量A。

此外,您可能不应该使用信号量本身,因为它们的性能比为多线程设计的实际关键部分机制要慢得多(我使用信号量作为示例,因为它们是编程语言中最普遍的名称)。信号量用于系统广泛使用。

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Semaphore.html Java信号量