【发布时间】:2022-01-23 07:08:55
【问题描述】:
我目前正在开发自己的小棋盘游戏,但遇到了多线程问题。我有一个渲染板的线程和一个提供要渲染的数据的线程。供应线程将他的数据写入一个数组,然后渲染器获取此数据并将其渲染到屏幕上(渲染线程从不向数组写入任何内容)。因此,我开始阅读有关线程之间的多线程和共享对象和数组以及数组上的 volatile 关键字的信息,并发现使数组 volatile 并不能解决问题。然后我读到了happens-before关系,有点困惑。 https://docs.oracle.com/javase/6/docs/api/java/util/concurrent/package-summary.html#MemoryVisibility 这么说
监视器的解锁(同步块或方法退出)发生在同一监视器的每个后续锁定(同步块或方法入口)之前。并且由于happens-before关系是可传递的,因此线程在解锁之前的所有动作都发生在任何线程锁定该监视器之后的所有动作之前。
因此,如果我理解正确,我将不得不以同步方法对数组进行读写,所以在这段代码中,读取器总是拥有写入器写入数组的数据?
class Test {
private static String[] data = new String[10];
public synchronized String read(int index) {
return data[index];
}
public synchronized void write(String value, int index) {
data[index] = value;
}
private Thread writer = new Thread(() -> {
while(true) {
write("Test", 0);
System.out.println("Wrote " + read(0) + " to 0.");
try {
Thread.sleep(10000);
} catch (InterruptedException exc) {
//Handle exception
}
}
});
private Thread reader = new Thread(() -> {
while(true) {
System.out.println("Read " + read(0) + " from 0.");
try {
Thread.sleep(10000);
} catch (InterruptedException exc) {
//Handle exception
}
//Render the data
});
public static void main(String[] args){
writer.start();
reader.start();
}
}
谢谢。
PS。我不是母语人士,所以请原谅一些语法错误。
【问题讨论】:
-
在 Internet 上搜索 java producer consumer 并阅读 Oracle 的 Java 教程中的 Concurrency 课程。你的
writer线程是生产者,你的reader线程是消费者。
标签: java arrays multithreading