JAVA多线程-对象及变量的并发访问(二)volatile关键字
来源:互联网 发布:linux 串口 select 编辑:程序博客网 时间:2024/04/28 12:27
三、Volatile关键字
关键字volatile的主要作用是使变量在多个线程间可见。
3.1 关键字volatile与死循环
测试案例: 我想通过改变flag的值,从而停止对service的test()方法,进行停止。
<span style="font-size:18px;">package org.jksoft.thread.Volatile;public class Test1 {public static void main(String[] args) {Service service = new Service();service.test();System.out.println("我要停止他。。。。");service.setFlag(false);}}class Service{private boolean flag = true;public boolean isFlag() {return flag;}public void setFlag(boolean flag) {this.flag = flag;}public void test(){while(flag){System.out.println("run test threadName="+Thread.currentThread().getName());try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}</span>测试结果:
结果分析:
由于test()方法尚未执行完成,所以主线程(main)不会执行后续代码。如果想要解决,当然是用多线程技术了。
3.2 解决同步死循环
代码清单:
package org.jksoft.thread.Volatile;public class Test2 {public static void main(String[] args) {final Service2 s2 = new Service2();Thread thread = new Thread(new Runnable() {public void run() {s2.test();}},"service2");thread.start();try {Thread.sleep(5000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("我要停止他。。。。");s2.setFlag(false);}}class Service2{private volatile boolean flag = true;public boolean isFlag() {return flag;}public void setFlag(boolean flag) {this.flag = flag;}public void test(){while(flag){System.out.println("run test threadName="+Thread.currentThread().getName());try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}测试结果:
注意:如果没有添加volatile,那么同样的程序运行在JVM为-server服务器的环境中,会出现死锁。
原因:
1、-server模式为了线程运行的效率,线程一直在私有堆栈中取得的flag的值为true,而main中设置的flag=false,更新的却是公共堆栈中的flag值。
2、而volatile的作用就是强制从公共堆栈中取得变量的值,而不是从线程私有数据栈中取得变量的值。
3、总而言之,就是由于私有堆栈中的值和公共堆栈的值不同步造成的。
3.3 volatile与synchronized的比较
使用volatile关键字,增加了实例变量在多个线程之间的可见性,但volatile关键字最致命的缺点是不支持原子性。
1、关键字volatile是线程同步的轻量级表现,所以volatile的性能肯定比synchronized要好,并且volatile只能修饰于变量,而synchronized可以修饰方法,以及代码块。
2、多线程访问volatile不会发生阻塞,而synchronized会出现阻塞
3、volatile能保证数据的可见性,但是不能保证原子性。而synchronized可以保证原子性,也可以间接保证可见性,以为它会将私有内存和公共内存的数据作同步。
4、关键字volatile解决的是变量在多个线程之间的可见性;而synchronized关键字解决的是多个线程之间访问资源的同步性。
小结:线程安全包含原子性和可见性两个方面,java的同步机制都是围绕这两个方面来确保线程安全的。
- JAVA多线程-对象及变量的并发访问(二)volatile关键字
- 多线程编程核心技术读书笔记(二):对象及变量的并发访问(volatile关键字)
- 多线程编程核心技术读书笔记(二):对象及变量的并发访问(synchronized关键字)
- 《Java多线程编程核心技术》(二)对象及变量的并发访问
- Java多线程编程核心技术---对象及变量的并发访问(二)
- Java多线程二——对象及变量的并发访问(概念理解)
- Java多线程核心技术(二):对象及变量的并发访问访问
- 多线程编程学习二(对象及变量的并发访问)
- 多线程编程学习二(对象及变量的并发访问)
- 多线程编程学习二(对象及变量的并发访问)
- java多线程编程2--对象及变量的并发访问
- java多线程编程3--对象及变量的并发访问
- Java多线程--对象及变量的并发访问
- Java多线程之对象及变量的并发访问
- (转载)多线程编程学习二(对象及变量的并发访问)
- Java并发编程学习(二)—— 对象及变量的并发访问
- JAVA多线程-对象及变量的并发访问(一)synchronized详解
- Java多线程编程核心技术---对象及变量的并发访问(一)
- 1017. Queueing at Bank (25)
- kali安装后详细配置
- 值得推荐的C/C++框架和库
- MVC的学习用PPT
- 假脱机技术
- JAVA多线程-对象及变量的并发访问(二)volatile关键字
- 技术大牛小星星眼中的项目管理
- 创建安卓app的30个经验教训
- Android笔记 标题栏ActionBar
- BZOJ 4292 [PA2015] Równanie - 数位&思维
- PopupWindow和AlertDialog区别
- 印度网站前50名都是做什么的
- 【Mybatis】Parameter 'xxx' not found. Available parameters are [1, 0, param1, param2]
- ssm Springmvc+spring+hibernate