Java提高——JUC线程volatile关键和内存可见性
内存可见性
- 内存可见性:是指当某个线程正在使用对象状态而另一个线程在同时修改该状态,需要确保当一个线程修改了对象状态之后,其他线程能够看到发生的状态变化。
- 可见性错误:当读操作与写操作在不同的线程中执行时,我们无法确保执行读操作的线程能实时的看到其他线程写入的值,有时甚至是不可能的事情。
- 我们可以通过对象同步来保证对象被安全的发布。除此之外我们也可以使用一种更加轻量级的volatile变量。
class Condition implements Runnable{ private boolean flag = false; public void setFlag(boolean flag) { this.flag = flag; } public boolean isFlag(){ return flag; } @Override public void run() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } flag = true; System.out.println("flag 已经变为 "+isFlag()); } } public class TestVolatile { public static void main(String[] args) { Condition con = new Condition(); new Thread(con).start(); while (true){ if (con.isFlag()){ System.out.println("=====阿西吧====="); break; } } } }
上面的main线程和Condition线程并没有共享flag变量。
当我们运行程序时,JVM会为每个线程分配一个独立的缓存用于提高效率
解决方案一:使用同步块(可以每次都刷新缓存重复的到主存中读数据)
public class TestVolatile { public static void main(String[] args) { Condition con = new Condition(); new Thread(con).start(); while (true){ synchronized (TestVolatile.class) { if (con.isFlag()) { System.out.println("=====阿西吧====="); break; } } } } }
但是锁会使效率低下。
解决方案二:volatile关键字(效率也会降低但是比锁的效率高)
1、java中的volatile关键字提供了一种稍弱的同步机制,用来确保将变量的更新操作通知到其他线程。可以将volatile看做是一个轻量级的锁,但是又与锁有些不同:
- 对于多线程,不是一种互斥关系
- 不能保证变量状态的“原子性操作”
/** * @author chenpeng * @date 2018/7/10 15:23 * * volatile关键字:保证多个线程访问共享数据时,彼此的数据是可见的 * (原理就是实时把缓存中的数据刷新到主存中) * 相较于synchronized是一种轻量级的同步策略 * * 注意: * 1、volatile不具备“互斥性” * 2、volatile不能保证变量的“原子性” */ class Condition implements Runnable{ private volatile boolean flag = false; public void setFlag(boolean flag) { this.flag = flag; } public boolean isFlag(){ return flag; } @Override public void run() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } flag = true; System.out.println("flag 已经变为 "+isFlag()); } } public class TestVolatile { public static void main(String[] args) { Condition con = new Condition(); new Thread(con).start(); while (true){ if (con.isFlag()) { System.out.println("=====阿西吧====="); break; } } } }