如何从调用同一变量的两个线程中获取相同的值?
How do I get an identical value from two threads calling on the same variable?
我有一个程序,首先创建一个 GUI 来处理用户输入并显示输出。
首先发生的事情是创建 window,然后调用 Functions Class 方法 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();
}
});
}
调用 Functions Class 方法 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;
}
}
调用 Class 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();
}
}
和 Class 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());
}
}
我遇到的主要问题是,由于对线程的了解很少,我似乎使函数 class 中的 serverStatus() 布尔值等于两个不同的东西。其中 ConsoleOutputReader 的输出为真,ConsoleInputWriter 的输出为假。 我如何确保当我启动两个线程时它们在调用方法时看到相同的值?
我已经让这段代码与两个线程一起工作,其中主线程 运行 输入和第二个线程用于 运行 输出,但我想尝试设置它这个。
也非常欢迎对我的风格和/或我使用的模式提出任何建议。
编辑:我意识到我所有的 f运行tic 变化,无论 class 调用 initServer() 是 class 在他们调用 serverStatus 时变为真().
任何为两个线程更改对象的方法都需要同步。当方法运行时,如果对象在更改时被一个或两个线程读取,则线程可能读取不同的值。
e.x.:
public static synchronized void initServer(boolean bool) { init = bool; }
我有一个程序,首先创建一个 GUI 来处理用户输入并显示输出。
首先发生的事情是创建 window,然后调用 Functions Class 方法 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();
}
});
}
调用 Functions Class 方法 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;
}
}
调用 Class 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();
}
}
和 Class 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());
}
}
我遇到的主要问题是,由于对线程的了解很少,我似乎使函数 class 中的 serverStatus() 布尔值等于两个不同的东西。其中 ConsoleOutputReader 的输出为真,ConsoleInputWriter 的输出为假。 我如何确保当我启动两个线程时它们在调用方法时看到相同的值?
我已经让这段代码与两个线程一起工作,其中主线程 运行 输入和第二个线程用于 运行 输出,但我想尝试设置它这个。
也非常欢迎对我的风格和/或我使用的模式提出任何建议。
编辑:我意识到我所有的 f运行tic 变化,无论 class 调用 initServer() 是 class 在他们调用 serverStatus 时变为真().
任何为两个线程更改对象的方法都需要同步。当方法运行时,如果对象在更改时被一个或两个线程读取,则线程可能读取不同的值。
e.x.:
public static synchronized void initServer(boolean bool) { init = bool; }