简体   繁体   English

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

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

I have a program that starts by creating a GUI to handle user input and display the output.我有一个程序,它首先创建一个 GUI 来处理用户输入并显示输出。

The first thing that happens is the window is created and then the Functions Class method initServer() is called to initialize some variables for the input and output portion发生的第一件事是创建窗口,然后调用函数类方法 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();
        }

    });
}

With the Functions Class method initServer() being called, We start the process then follow by initializing the i/o variable that will handle all the streams being used to communicate with the process.调用函数类方法 initServer() 后,我们启动进程,然后初始化 i/o 变量,该变量将处理用于与进程通信的所有流。 Then we start the two threads - ConsoleInputWriter and ConsoleOutputReader - responsible for handling Input and Output to the process.然后我们启动两个线程——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;
    }

}

Once called the Class ConsoleOutputReader starts and executes a command for the process to start a Jar File and confirms that the i/o streams have been initialized before it tries to get any output.一旦被调用,类 ConsoleOutputReader 就会启动并执行进程的命令以启动 Jar 文件,并在尝试获取任何输出之前确认 i/o 流已初始化。 If it continues to the while loop we should be getting output.如果它继续到 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();
    }


}

and the Class ConsoleInputWriter follows right after ConsoleOutputReader also confirming that the serverInit() boolean is true, then to wait in a while loop for an input from the user. 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());

    }
}

The main issue I have is that with minimal knowledge on threads I seemed to have made the serverStatus() boolean from the Functions class equal two different things.我遇到的主要问题是,在对线程了解最少的情况下,我似乎使 Functions 类中的 serverStatus() 布尔值等于两个不同的东西。 where the output from ConsoleOutputReader is true and the output from ConsoleInputWriter is false.其中 ConsoleOutputReader 的输出为 true,ConsoleInputWriter 的输出为 false。 How would I make sure that when I start both threads they're seeing the same value when they call the method?我如何确保当我启动两个线程时,他们在调用方法时看到相同的值?

I've gotten this code to work with two threads where the main thread ran the inputs and a second thread was used to run the outputs, but I wanted to try it setup like this.我已经让这段代码与两个线程一起工作,其中主线程运行输入,第二个线程用于运行输出,但我想尝试像这样设置。

Any tips to my style and or patterns I use are also very welcome.任何关于我的风格和/或我使用的模式的提示也非常受欢迎。

Edit: I realized with all my frantic changes that whatever class calls initServer() is that class that get true when they call serverStatus().编辑:我疯狂地意识到,任何调用 initServer() 的类都是在调用 serverStatus() 时变为 true 的类。

Any methods that change an object for both threads need to be synchronized.任何更改两个线程的对象的方法都需要同步。 When the method runs, if the object is being read by one or both of the threads while it changes, The threads could read different values.当该方法运行时,如果对象在更改时被一个或两个线程读取,则这些线程可以读取不同的值。

ex:前任:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从两个不同的线程访问相同的变量 - Accessing same variable from two different threads 从同一表读取两个线程:如何使两个线程不从TASKS表读取同一组数据 - Two threads reading from the same table:how do i make both thread not to read the same set of data from the TASKS table 两个线程,相同的静态变量,相同的值,并发访问 - Two threads, same static variable, same value, concurrent access 如何从同一文本字段中获得两个值? - How do I get two values from same text field? 我有两个线程,这两个线程几乎是完全相同的,但是只有其中之一会出现CalledFromWrongThreadException错误。 为什么? - I have two threads that two almost identical things but get CalledFromWrongThreadException error on only one of them. why? 如何从一个inputStream中读取两个线程? - How can I get two threads to read from one inputStream? 两个线程使用相同的变量 - Two threads using same variable Java-如何从多个线程获取或创建连接 - Java - How do I get or create a connection from multiple threads 当两个线程同时使用@Transactional访问一个方法时,我们获得多少交易? - How many transactions do we get when two threads visit a method with @Transactional at the same time? 两个线程获得相同的值 - Two threads getting same value
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM