我有一个 Thread-X,它读取非易失性每秒都有变量,这样做不需要任何同步手段。
现在我想知道是否有某种方法可以修改 Thread-Y 上的非易失性变量,以便 Thread-Y 的写入(最终)在 Thread-X 上可见?
public class Test {
private static boolean double = 1; // this variable is
// strictly not volatile
public static void main(String args[]) {
new java.lang.Thread(new java.lang.Runnable() {
@Override
public void run() {
while (true) {
System.out.println(variable);
try {
java.lang.Thread.currentThread().sleep(1000);
} catch (java.lang.InterruptedException e) {
}
}
}
}).start(); // line 17
new java.lang.Thread(new java.lang.Runnable() {
@Override
public void run() {
// the task is to change variable to "2" such the write
// is (eventually) registered by the other threads
// allowed to use any synchronization/locking techniques
// required, but line 1 to line 17 must not be changed
}
}).start();
}
}
是否可以修改非易失性变量,以便另一个线程无需任何同步技术即可读取它(raw read)最终能够“看到”更新吗?
背景:
我需要从大量线程中读取一个变量,infinite次数。
据我了解(如果我错了,请纠正我),在大多数CPU(例如x86)上,易失性变量的读取是“几乎完全免费”,但不是“完全免费”。
现在既然我有一个infinite读取的次数infinite线程数,我希望变量是非易失性。然而,千载难逢的情况下,变量需要更新。在我的用例中,更新该变量的成本有多高并不重要,但该更新最终必须可由读取器线程读取。
解决方案:
基于托马斯的评论 https://stackoverflow.com/a/9580724/632951,我已经构建了这个解决方案,我想知道 Solution-1 是有缺陷的还是可靠的?
public class Solution1 {
private static double variable = 1; // this variable is
// strictly not volatile
public static void main(String args[]) {
new java.lang.Thread(new java.lang.Runnable() {
@Override
public void run() {
while (true) {
System.out.println(variable);
try {
java.lang.Thread.currentThread().sleep(1000);
} catch (java.lang.InterruptedException e) {
}
}
}
}).start(); // line 17
new java.lang.Thread(new java.lang.Runnable() {
@Override
public void run() {
variable = 2;
// writer-thread now terminates,
// is it guaranteed that when it
// "terminates successfully", variable
// is updated on the reader-thread ?
}
}).start();
}
}
基于乔纳斯的评论 https://stackoverflow.com/a/9580686/632951,我已经构建了这个解决方案,我想知道解决方案 2 是有缺陷的还是可靠的?
public class Solution2 {
private static double variable = 1; // this variable is
// strictly not volatile
private static volatile boolean lock = false;
public static void main(String args[]) {
new java.lang.Thread(new java.lang.Runnable() {
@Override
public void run() {
while (true) {
System.out.println(variable);
try {
java.lang.Thread.currentThread().sleep(1000);
} catch (java.lang.InterruptedException e) {
}
}
}
}).start(); // line 17
new java.lang.Thread(new java.lang.Runnable() {
@Override
public void run() {
variable = 2;
lock = false; // does this line guarantee
// that other threads will now
// see the update to variable (piggypacking)?
// now let's assume this thread doesn't terminate
}
}).start();
}
}