这里有三个简单的类:
第1类:
public class ThreadSyncMain {
public static int count = 0; // volatile is not use
public static void main(String[] args) {
Thread thread1 = new Thread( new Thread1(),"Thread1" );
Thread thread2 = new Thread( new Thread2(),"Thread2");
thread1.start();
thread2.start();
}
}
第2类:
public class Thread1 implements Runnable{
public void run() {
System.out.println("Thread1 Count :: "+ThreadSyncMain.count);
ThreadSyncMain.count++;
}
}
第3类:
public class Thread2 implements Runnable{
public void run() {
System.out.println("Thread2 Count :: "+ThreadSyncMain.count);
}
}
输出为:
线程1计数:: 0
线程2计数:: 1
这意味着线程1更改了计数值。那么为什么线程1中的更改会影响线程2,因为我没有使用任何“volatile”关键字。在这种情况下,“volatile”关键字不是问题吗?如何修改代码以测试“volatile”?
提前致谢。
更新部分:
经过一些命中和试用测试后,我正在更新代码。 1类保持不变。这是更新的代码:
第2类:我增加了100毫秒的延迟。
public class Thread1 implements Runnable{
public void run() {
System.out.println("Thread1 Count :: "+ThreadSyncMain.count);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
ThreadSyncMain.count++;
}
}
第3类:添加了while循环。内部持续监控计数。
public class Thread2 implements Runnable{
public void run() {
while(true)
{
if(ThreadSyncMain.count == 1)
{
System.out.println("Thread2 Count :: "+ThreadSyncMain.count);
}
}
}
}
现在在这种情况下,我得到以下输出:
1.如果在class1中未使用“volatile”,则输出为:
Thread1 Count :: 0
2.如果在class1中使用“volatile”,则输出为:
Thread1 Count :: 0
Thread2 Count :: 1
Thread2 Count :: 1
Thread2 Count :: 1
.
.
.
为什么在这种情况下会出现挥发物?
参考方案
每个线程都有一个内存视图。如果不使用锁,则不能保证这些视图在线程之间是一致的。这样,共享变量就可以了,因为您可以在线程中看到它,所以可以像上面一样共享一个变量(没有volatile
),但是会给您不可靠的结果。使用volatile
关键字意味着在线程之间始终读取变量。
参见here,特别注意:
Volatile 字段是用于通信的特殊字段
线程之间的状态。每次读取volatile将看到最后一次写入
通过任何线程来解决该问题;实际上,它们是由
程序员作为永远都无法看到“过时”的领域
缓存或重新排序的结果。
我的模式类似于OR:“word1 | word2 | word3”我大约有800个字。可能有问题吗? 参考方案 您仅受记忆和理智的限制。 :)
Java:线程池如何将线程映射到可运行对象 - java试图绕过Java并发问题,并且很难理解线程池,线程以及它们正在执行的可运行“任务”之间的关系。如果我创建一个有10个线程的线程池,那么我是否必须将相同的任务传递给池中的每个线程,或者池化的线程实际上只是与任务无关的“工人无人机”可用于执行任何任务?无论哪种方式,Executor / ExecutorService如何将正确的任务分配给正确的线程? 参考方案 …
Java-搜索字符串数组中的字符串 - java在Java中,我们是否有任何方法可以发现特定字符串是字符串数组的一部分。我可以避免出现一个循环。例如String [] array = {"AA","BB","CC" }; string x = "BB" 我想要一个if (some condition to tell wheth…
Java:我可以在Hashmaps中使用数组吗? - java我可以在Hashmaps中使用数组吗?如果是这样,则声明这种哈希图的确切语法是什么?谢谢 参考方案 数组也是对象。甚至像int[]这样的原始数组。Map<String,String[]> map = new HashMap<String,String[]>();
JAVA:字节码和二进制有什么区别? - javajava字节代码(已编译的语言,也称为目标代码)与机器代码(当前计算机的本机代码)之间有什么区别?我读过一些书,他们将字节码称为二进制指令,但我不知道为什么。 参考方案 字节码是独立于平台的,在Windows中运行的编译器编译的字节码仍将在linux / unix / mac中运行。机器代码是特定于平台的,如果在Windows x86中编译,则它将仅在Win…