java - 在已实现的 Java 代码中需要有关易失性和非易失性概念的帮助?
问题描述
我编写了以下代码来理解 java 中的 volatile 概念,但输出似乎令人困惑而不是澄清概念。欢迎和赞赏更正、澄清和反馈。
package threading;
public class UnSyncRead {
//volatile static int value = 987;
static int value = 987;
public static void main(String[] args) {
ThreadEx4 t = new ThreadEx4(value);
t.start();
for(int i=0;i<4;i++) {
Thread thread = new Thread( new ThreadEx3(value));
thread.start();
}
}
}
class ThreadEx3 implements Runnable{
private int i;
public ThreadEx3(int i) {
this.i=i;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getId()+ " "+Thread.currentThread().getName()+" "+ " inside "+i);
}
}
class ThreadEx4 extends Thread{
private int i;
public ThreadEx4(int i) {
this.i=i;
}
public void run() {
++i;
System.out.println("changed the value to "+i);
}
}
该程序给出以下输出
changed the value to 988
12 Thread-1 inside 987
13 Thread-2 inside 987
14 Thread-3 inside 987
15 Thread-4 inside 987
但是,如果我通过执行以下更改并运行代码来修改代码以使其value
可变。volatile
public class UnSyncRead {
volatile static int value = 987;
//static int value = 987;
public static void main(String[] args) {
ThreadEx4 t = new ThreadEx4(value);
t.start();
for(int i=0;i<4;i++) {
Thread thread = new Thread( new ThreadEx3(value));
thread.start();
}
}
}
当我在没有 volatile 关键字的情况下运行它时,我得到了完全相同的输出。
changed the value to 988
12 Thread-1 inside 987
13 Thread-2 inside 987
14 Thread-3 inside 987
15 Thread-4 inside 987
我的问题是为什么 for 循环中的线程仍在读取value
变量 as987
和 not的值988
,即使在实现 volatile 关键字之后也是如此。
将深深感谢这个问题的答案。
解决方案
这与多线程完全无关,这是一个更基本的问题。
class ThreadEx4 extends Thread{
private int i;
public ThreadEx4(int i) {
this.i=i;
}
public void run() {
++i;
System.out.println("changed the value to "+i);
}
}
您在此处更改私有变量i
,而不是全局static
字段。
Java 通过值传递事物。所以当你说new ThreadEx4(myInteger)
的时候,构造函数会收到里面的数字myInteger
。它对其本地副本所做的任何事情都不会产生任何影响myInteger
。
要继续您的多线程实验,请摆脱局部变量并执行
class Ex4 extends Runnable {
@Override
public void run(){
int newValue = ++UnSyncRead.value;
System.out.println("changed the value to "+newValue);
}
}
// and the same for the other runnables
推荐阅读
- excel - 如果我在带箭头的文本框中输入“V”,想要使用左函数突出显示该行
- javascript - 将firebase电话号码保存到本地存储变量
- php - 使用静态类成员作为超级全局变量的php线程安全
- apache-kafka - Kafka生产者表现不佳
- javascript - JavaScript 原型问题:我不明白这个错误
- delphi - 输入时如何填充 ComboBox?
- jquery - 将类型文件中的数据发送到 ASP.NET MVC 中的控制器
- android - 根据位置滚动Recyclerview时获取数据
- python - 如何生成排列列表列表
- python - 有没有什么节省内存的方法来计算两个稀疏矩阵的皮尔逊相关系数?