您的位置:首页 > 编程语言 > Java开发

java并发编程——violate关键字使用场景

2015-11-21 00:00 746 查看
摘要: java并发编程——violate关键字使用场景

package com.fsun.research.thread.violate;

public class MainTest {
private static boolean ready;
private static class CounterThread implements Runnable{

@Override
public void run() {
while(!ready){

}
}

}
public static void main(String[] args) {
new Thread(new CounterThread()).start();
System.out.println("主线程睡眠300毫秒");
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
ready=true;
}
}


上面的例子中run方法会陷入到死循环中,这是因为CounterThread线程在主线程改变ready值之前已经从主内存中读取了ready的值到自己的工作内存(主线程睡眠300毫秒就是为了保证这一点),由于在while循环中不停大量的循环读取,jvm为了提高读取效率,对于这种高并发读取的情况是从线程的工作内存来读取,即使当主线程睡眠醒来改变了ready的值并更新了主内存但却并没有什么卵用。

再看下面一个例子:

package com.fsun.research.thread.violate;

public class MainTest {
private static boolean ready;
private static class CounterThread implements Runnable{

@Override
public void run() {
System.out.println("ready====="+ready);
try {
Thread.sleep(1000);  //睡眠1秒
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("1秒后读取到ready的值"+ready);
}

}
public static void main(String[] args) {
new Thread(new CounterThread()).start();
System.out.println("主线程睡眠300毫秒");
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
ready=true;
}
}


主线程睡眠300毫秒为了保证CounterThread在主线程更新ready之前从主内存中读取到ready的值。CounterThread在睡眠1秒之后又读取ready的值,此时读取到了主线程更新过后的值。为了使程序的执行流程可控加入了线程休眠,实际上在测试的过程中不加入线程休眠,只要线程不在短时间内频繁的读取ready的值都没有出现读取到的ready的值错误的情况。

可见在高并发的情况下,对于共享变量jvm并不能保证每个线程读取到的值都是一样的。violate此时正好派上用场。关于violate关键字请自行谷歌。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: