[英]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.