簡體   English   中英

如何從調用同一個變量的兩個線程中獲得相同的值?

[英]How do I get an identical value from two threads calling on the same variable?

我有一個程序,它首先創建一個 GUI 來處理用戶輸入並顯示輸出。

發生的第一件事是創建窗口,然后調用函數類方法 initServer() 為輸入和輸出部分初始化一些變量

private JFrame frame;

public static Functions func = new Functions();

public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {

        public void run() {
            Thread.currentThread().setName("Console");
            System.out.println(Thread.currentThread().getName() + " [" + Thread.currentThread().getId() + "] Started");

            try {
                Console window = new Console();
                window.frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }

            func.initServer();
        }

    });
}

調用函數類方法 initServer() 后,我們啟動進程,然后初始化 i/o 變量,該變量將處理用於與進程通信的所有流。 然后我們啟動兩個線程——ConsoleInputWriter 和 ConsoleOutputReader——負責處理進程的輸入和輸出。

public class Functions {

    private ConsoleOutputReader cor = new ConsoleOutputReader();
    private ConsoleInputWriter ciw = new ConsoleInputWriter();

    private OutputStreamWriter osw;
    private InputStreamReader isr;

    private BufferedWriter bw;
    private BufferedReader br;

    private BufferedReader input = new BufferedReader(new InputStreamReader(System.in));

    private File serverJar;

    private String serverPath;

    private ProcessBuilder builder;
    private Process proc;

    private boolean init = false;

    public void initServer() 
    {
        updateConsole("Server Initiated Status: " + serverStatus());

        builder = new ProcessBuilder("/bin/bash");

        try {
            proc = builder.start();
        } catch (IOException e) {
            e.printStackTrace();
        }

        osw = new OutputStreamWriter(proc.getOutputStream());
        bw = new BufferedWriter(osw);

        isr = new InputStreamReader(proc.getInputStream());
        br = new BufferedReader(isr);

        serverStatus(true);
        updateConsole("Server Initiated Status: " + serverStatus());

        cor.start();
        ciw.start();
    }

    public String recieveInput() 
    {
        String s = null;
        try {
            s = input.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return s;
    }

    public boolean serverStatus() 
    {
        return init;
    }

    public void serverStatus(boolean status) 
    {
        init = status;
    }

    public void exec(String cmd)
    {
        try {
            bw.write(cmd);
            bw.newLine();
            bw.flush();
        } catch (IOException e) {
            updateConsole("Cant run: [" + cmd + "] :::::::: " + e);
            e.printStackTrace();
        }
    }

    public void updateConsole()
    {
        //edit to print to textPane
        try {
            System.out.println(br.readLine());
        } catch (IOException e) {

        }
    }

    public void updateConsole(String s)
    {
        System.out.println(s);
    }

    public File getJar(/**String s**/) 
    {
        serverJar = new File(Functions.class.
                getResource("CraftBukkit.jar").getPath());
        return serverJar;
    }

    public void setPath(String s) 
    {
        serverPath = s;
    }


    public String getPath() 
    {
        return serverPath;
    }

}

一旦被調用,類 ConsoleOutputReader 就會啟動並執行進程的命令以啟動 Jar 文件,並在嘗試獲取任何輸出之前確認 i/o 流已初始化。 如果它繼續到 while 循環,我們應該得到輸出。

public class ConsoleOutputReader extends Thread{

    private static Functions func = new Functions();

    public void run()
    {
        currentThread().setName("cor");
        System.out.println(currentThread().getName() + " [" + Thread.currentThread().getId() + "] Started");

        func.exec("cd " + "~/Desktop/Bukkit" + " && java -Xmx1024M -jar " + func.getJar() + " -o true");

        while(func.serverStatus())
            func.updateConsole();
    }


}

ConsoleInputWriter 類緊跟在 ConsoleOutputReader 之后,也確認了 serverInit() 布爾值為真,然后在 while 循環中等待來自用戶的輸入。

public class ConsoleInputWriter extends Thread{

    public static Functions func = new Functions();

    public void run()
    {
        currentThread().setName("ciw");
        func.updateConsole(currentThread().getName() + " [" + Thread.currentThread().getId() + "] Started");

        while(func.serverStatus()) 
            func.exec(func.recieveInput());

    }
}

我遇到的主要問題是,在對線程了解最少的情況下,我似乎使 Functions 類中的 serverStatus() 布爾值等於兩個不同的東西。 其中 ConsoleOutputReader 的輸出為 true,ConsoleInputWriter 的輸出為 false。 我如何確保當我啟動兩個線程時,他們在調用方法時看到相同的值?

我已經讓這段代碼與兩個線程一起工作,其中主線程運行輸入,第二個線程用於運行輸出,但我想嘗試像這樣設置。

任何關於我的風格和/或我使用的模式的提示也非常受歡迎。

編輯:我瘋狂地意識到,任何調用 initServer() 的類都是在調用 serverStatus() 時變為 true 的類。

任何更改兩個線程的對象的方法都需要同步。 當該方法運行時,如果對象在更改時被一個或兩個線程讀取,則這些線程可以讀取不同的值。

前任:

public static synchronized void initServer(boolean bool) { init = bool; }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM