Bev*_*vor 5 java concurrency multithreading volatile synchronized
我读了几篇关于并发性问题的帖子,但我仍然不确定某些事情.我可以说当使用synchronized时,我免费获得易失性功能,因为当释放对象的锁定时,下一个线程总是读取修改后的对象.对于volatile,对象的值会立即反映到其他线程.但是当我使用synchronized时,由于对象的锁定,不可能立即反映它.释放锁定后,只有另一个线程可以访问它.所以我不必关心立即将值反映到其他线程.我理解这个吗?
[更新]
示例打印总是1 2 3 4 5 6 7 8 9没有易失性.
package main;
public class Counter
{
public static long count = 0;
}
public class UseCounter implements Runnable
{
public void increment()
{
synchronized (this)
{
Counter.count++;
System.out.print(Counter.count + " ");
}
}
@Override
public void run()
{
increment();
increment();
increment();
}
}
public class DataRace
{
public static void main(String args[])
{
UseCounter c = new UseCounter();
Thread t1 = new Thread(c);
Thread t2 = new Thread(c);
Thread t3 = new Thread(c);
t1.start();
t2.start();
t3.start();
}
}
Run Code Online (Sandbox Code Playgroud)
不,根据 Java 内存模型,同步访问并不暗示易失性访问(尽管在特定实现上,可能是这样,但您不应该依赖于此)
\n\nJava 语言规范 17.4.4(关于 Java 内存模型):
\n\n\n\n\n同步操作会引发操作上的同步关系,定义如下:
\n\n\n
\n- \n
监视器 m 上的解锁操作与 m 上的所有后续锁定操作同步(其中“后续”是根据同步顺序定义的)。
- \n
对易失性变量 v (\xc2\xa78.3.1.4) 的写入与任何线程对 v 的所有\n 后续读取进行同步(其中“后续”是根据同步顺序定义的)。
volatile对变量进行操作,并对synchronized对象的监视器(“锁”)进行操作。
如果一个线程 A 刚刚退出对象O上的同步块,而另一个线程 B 刚刚读取对象O上的易失性变量(实例字段) V,则两个线程之间仍然不存在同步关系。无法保证线程 A 会看到线程 B 所做的任何数据修改,反之亦然,直到线程 B 也在对象O上同步,或者直到线程 A 也访问对象O上的易失性字段V为止。
\n| 归档时间: |
|
| 查看次数: |
183 次 |
| 最近记录: |