学校网站设计首页,wordpress插件视频去广告 ck-video0.65.zip,云主机免费,佛山做网站yunzhanfsjvm线程的内存模型 看图#xff0c;简单来说线程中操作的变量是副本。在并发情况下#xff0c;如果数据发生变更#xff0c;副本的数据就变为脏数据。这个时候就会有并发问题。
参考#xff1a;https://www.cnblogs.com/yeyang/p/12580682.html
怎么解决并发问题
解决的…jvm线程的内存模型 看图简单来说线程中操作的变量是副本。在并发情况下如果数据发生变更副本的数据就变为脏数据。这个时候就会有并发问题。
参考https://www.cnblogs.com/yeyang/p/12580682.html
怎么解决并发问题
解决的方案有两种
1. 加排它锁将并发的操作变成串行的操作。
2. 无锁方案通过cas操作并保证如果变量发生变更其它的线程需要立即知道。java的原子操作类使用的就是这种方案casvolatile
volatile关键字实战
先说结论, 从实战效果上看whlie循环中的变量是无法感知到其它线程对变量的修改的但是再加上volatile关键字修饰之后可以感知到。而for循环中即使不加关键字volatile修饰也是可以感知到变化的。这点在写代码时特别要注意。
测试代码如下
//结论 while循环的写法可以反应出变量的可见性问题for循环的写法不能反应可见性问题
public class Demo {static AtomicLong atomicLong new AtomicLong(0);public static int a 0;//public volatile static int a 0;SneakyThrowspublic static void main(String[] args) {test03();}//while循环在变量不加volatile关键字修饰时无法感知到变量变化。public static void test02() throws InterruptedException {Thread thread01 new Thread(new Runnable() {SneakyThrowsOverridepublic void run() {System.out.println(test01:a);while (true) {if (a 2) {System.out.println(我变了);}}}});thread01.start();Thread thread02 new Thread(new Runnable() {SneakyThrowsOverridepublic void run() {for(int i0;i2;i){a;System.out.println(test02: a);}}});thread02.start();Thread.sleep(10000);}//for循环即使不加volatile关键字修饰也可以感知到变量变化。public static void test03() throws InterruptedException {Thread thread01 new Thread(new Runnable() {SneakyThrowsOverridepublic void run() {System.out.println(test01:a);for(int i0; i10000; i){if (i0) {Thread.sleep(1000);}if (a 2) {System.out.println(我变了);}}}});thread01.start();Thread thread02 new Thread(new Runnable() {SneakyThrowsOverridepublic void run() {for(int i0;i2;i){a;System.out.println(test02: a);}}});thread02.start();Thread.sleep(10000);}
}