java并发编程——violate关键字使用场景
2015-11-21 00:00
746 查看
摘要: java并发编程——violate关键字使用场景
上面的例子中run方法会陷入到死循环中,这是因为CounterThread线程在主线程改变ready值之前已经从主内存中读取了ready的值到自己的工作内存(主线程睡眠300毫秒就是为了保证这一点),由于在while循环中不停大量的循环读取,jvm为了提高读取效率,对于这种高并发读取的情况是从线程的工作内存来读取,即使当主线程睡眠醒来改变了ready的值并更新了主内存但却并没有什么卵用。
再看下面一个例子:
主线程睡眠300毫秒为了保证CounterThread在主线程更新ready之前从主内存中读取到ready的值。CounterThread在睡眠1秒之后又读取ready的值,此时读取到了主线程更新过后的值。为了使程序的执行流程可控加入了线程休眠,实际上在测试的过程中不加入线程休眠,只要线程不在短时间内频繁的读取ready的值都没有出现读取到的ready的值错误的情况。
可见在高并发的情况下,对于共享变量jvm并不能保证每个线程读取到的值都是一样的。violate此时正好派上用场。关于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关键字请自行谷歌。
相关文章推荐
- Javase基础部分笔记之IO(一)
- 设计模式实例学习-模板方法
- 杭电ACM1003,1004,1005 java解答
- 4. Spring Boot 1.2.5,Spring Data JPA多数据源支持
- 第一次spring冲刺第9天
- 2. Spring Boot 1.2.5 不允许加载iframe问题解决
- myeclipse 调试JSP页面
- Eclipse编译Arduino程序不能使用串口函数Serial.begin解决办法
- 1. Spring Boot 1.2.5正式发布
- 工作第一天对spring+hibernate+未知框架感悟
- Spring maven打包成jar和war
- Java多线程之Lock的使用(转)
- java—数组(上)
- Jni 调试 : eclipse + Vs 联合调试
- 关于flexjson将json转为javabean的使用
- 简单实现spring里的BeanFactory实现原理
- 使用Java从云库里读取文件修改名称下载文件
- Spring代理方式1
- HashSet中消失的元素和多出来的元素
- Java中matches()方法声明