Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何从调用同一变量的两个线程中获得相同的值?_Java_Multithreading_Process_Processbuilder - Fatal编程技术网

Java 如何从调用同一变量的两个线程中获得相同的值?

Java 如何从调用同一变量的两个线程中获得相同的值?,java,multithreading,process,processbuilder,Java,Multithreading,Process,Processbuilder,我有一个程序,首先创建一个GUI来处理用户输入和显示输出 首先创建窗口,然后调用函数类方法initServer()来初始化输入和输出部分的一些变量 private JFrame frame; public static Functions func = new Functions(); public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public voi

我有一个程序,首先创建一个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()布尔值为true,然后在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()时实现的类。

任何更改两个线程对象的方法都需要同步。当方法运行时,如果对象在更改时被一个或两个线程读取,则线程可以读取不同的值

e、 十:


就我所见,InputWriter和OutputWriter各自创建了一个单独的
函数
对象,因此它们根本不相关。您是否打算只创建一个共享的
函数
对象?“输出为真/为假”是什么意思?我看不到任何写在任何地方的布尔值,你可能是说“是正确的/是错误的”@gurioso是的,我想创建一个对象,它们都应该从中调用。如果仔细查看这两个i/o类,它们会调用一个方法
serverStatus()
,这是一个布尔值,它必须为true,程序才能继续。但在你发布自己的帖子之前,先看看那里的一些帖子,它们有自己的手续。
public static synchronized void initServer(boolean bool) { init = bool; }