use*_*845 -1 java multithreading volatile synchronized java-memory-model
我正在尝试看看volatile这里的工作方式。如果声明cc为volatile,则输出如下。我知道线程执行输出有时会有所不同,但是我读到的volatile内容与相同synchronized,那么为什么要获得此输出?如果我使用两个实例,Thread1那有关系吗?
2线程-0
2线程1
4线程1
3线程-0
5线程1
6线程-0
7线程1
8线程-0
9线程1
10线程-0
11线程1
12线程-0
public class Volexample {
int cc=0;
public static void main(String[] args) {
Volexample ve=new Volexample();
CountClass count =ve.new CountClass();
Thread1 t1=ve.new Thread1(count);
Thread2 t2=ve.new Thread2(count);
t1.start();
t2.start();
}
class Thread1 extends Thread{
CountClass count =new CountClass();
Thread1(CountClass count ){
this.count=count;
}
@Override
public void run() {
/*for(int i=0;i<=5;i++)
count.countUp();*/
for(int i=0;i<=5;i++){
cc++;
System.out.println(cc + Thread.currentThread().getName());
}
}
}
class Thread2 extends Thread {
CountClass count =new CountClass();
Thread2(CountClass count ){
this.count=count;
}
@Override
public void run(){
/*for(int i=0;i<=5;i++)
count.countUp();*/
for(int i=0;i<=5;i++){
cc++;
System.out.println(cc + Thread.currentThread().getName());
}
}
}
class CountClass{
volatile int count=0;
void countUp(){
count++;
System.out.println(count + Thread.currentThread().getName());
}
}
}
Run Code Online (Sandbox Code Playgroud)
在Java中,volatile关键字的语义定义得很好。它们确保其他线程将看到对变量的最新更改。但是它们不会使读取-修改-写入操作成为原子操作。
因此,如果iis volatile和you do i++,则可以保证读取的最新值,i并且可以保证其他线程会i立即看到您的写入操作,但是不能保证两个线程不会交织它们的读/修改/写操作。因此,两个增量具有单个增量的效果。
假设i是一个易失性整数,其值初始化为零,除此以外没有写操作,并且有两个线程这样做i++;,可能会发生以下情况:
i。i。i。i。i是1,因此i现在访问的任何线程都将看到1。请注意,即使每个线程始终读取任何其他线程写入的最新值,增量也会丢失。该volatile关键字给出的知名度,而不是原子。
您可以synchronized用来形成复杂的原子操作。如果只需要简单的Atomic*类,则可以使用Java提供的各种类。
| 归档时间: |
|
| 查看次数: |
815 次 |
| 最近记录: |