概述:
Volatile是java提供的一种同步的手段,只不过它是轻量级的同步,为什么这么说,因为volatile只能保证多线程的内存可见性,不能保证多线程的原子操作。
运用场景:
1. 运算结果并不依赖变量的当前的值,或者能够确保只有单一线程修改改变量的值
1. 该变量没有包含在具体的其他变量的变式中
其实就是这个变量只提供读属性,不具备写和后期计算属性,只能读取,不能具体到业务中使用,就算需要使用,也只是做简单的逻辑判断,原子操作的。
volatile执行内存模型规则:
- 每次使用变量前必须先从主内存中刷新最新的值,用于保证能看见其他线程对变量的修改
- 每次修改后必须立刻同步回内存中,用于保证其他线程可以看到自己对变量的修改
- volatile修饰的变量不会被指令进行排序优化,保证代码的执行顺序
volatile实现线程关闭:
public class VolatileTest implements Runnable {
private volatile boolean flags = true;
@Override
public void run() {
int i = 0;
while (flags) {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("i==" + i++);
}
}
public boolean isFlags() {
return flags;
}
public void setFlags(boolean flags) {
this.flags = flags;
}
public static void main(String[] args) {
VolatileTest volatileTest = new VolatileTest();
Thread thread = new Thread(volatileTest);
thread.start();
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
volatileTest.setFlags(false);
}
}
volatile不具备原子性:
public class TicketWindowRunnable01 implements Runnable {
private volatile int a = 100;
@Override
public void run() {
while (a > 0) {
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " a = " + a--);
}
}
public static void main(String[] args) {
TicketWindowRunnable01 ticketWindowRunnable = new TicketWindowRunnable01();
for (int i = 0; i < 4; i++) {
Thread thread = new Thread(ticketWindowRunnable, "Thread" + i);
thread.start();
}
}
}