volatile关键字的主要作用是使变量在多个线程间可见。
关键字volatile的作用是强制从公共堆栈中取得变量的值,而不是从线程私有数据栈中取得变量的值。
1、关键字volatile与死循环:
package com.test; public class PringString { private boolean isContinuePrint = true; public boolean isContinuePrint() { return isContinuePrint; } public void setContinuePrint(boolean isContinuePrint) { this.isContinuePrint = isContinuePrint; } public void printStringMethod() { try { while (isContinuePrint == true) { System.out.println("run printStringMethod"); Thread.sleep(1000); } } catch (Exception e) { e.printStackTrace(); } } }
package com.test; public class Run { public static void main(String[] args) { PringString print = new PringString(); print.printStringMethod(); System.out.println("我要停止它"); print.setContinuePrint(false); } }
运行结果:
run printStringMethod
run printStringMethod
run printStringMethod
run printStringMethod
程序开始运行后,根本停不下来。因为main线程一直在处理while循环,导致程序不能继续执行后边的代码。解决的办法当然是多线程技术。
修改PringString.java:
package com.test; public class PringString extends Thread { volatile private boolean isContinuePrint = true; public boolean isContinuePrint() { return isContinuePrint; } public void setContinuePrint(boolean isContinuePrint) { this.isContinuePrint = isContinuePrint; } @Override public void run() { try { System.out.println("进入run了"); while (isContinuePrint == true) { System.out.println("run printStringMethod"); Thread.sleep(1000); } System.out.println("线程被停止了"); } catch (Exception e) { e.printStackTrace(); } } }
package com.test; public class Run { public static void main(String[] args) { try { PringString print = new PringString(); print.start(); Thread.sleep(1000); print.setContinuePrint(false); System.out.println("已经赋值为false"); } catch (Exception e) { e.printStackTrace(); } } }
运行结果:
进入run了
run printStringMethod
run printStringMethod
已经赋值为false
线程被停止了
总结:
使用volatile关键字增加了实例变量在多个线程之间的可见性。但volatile关键字最致命的缺点是不支持原子性。
下面是关键字synchronized和volatile进行一下比较:
- 关键字volatile是线程同步的轻量级实现,所以性能要比synchronized要好。并且volatile只能修饰于变量,而synchronized可以修饰方法,以及代码块。
- 多线程访问volatile不会发生阻塞,而synchronized会发生阻塞。
- volatile能保证数据的可见性,但不能保证原子性;而synchronized可以保证原子性,也可以间接保证可见性。因为它会将私有内存和公有内存中的数据做同步。
- volatile解决的是多个线程之间的可见性,而synchronized解决的是多线程之间的同步性.
关键字volatile主要使用场合是多个线程中可以感知实例变量被更改了,并且可以获得最新的使用值,此关键字提示线程每次从共享内存中读取变量,而不是从私有内存中读取,这样就保证了同步数据的可见性,但需要注意的是:如果修改实例变量中的数据,比如i++,就是i=i+1则这样的操作其实并不是一个原子操作,也就是非线程安全的。