volatile用于修饰变量在线程之间的可见性
当多个线程操作同一个变量时可用volatile修饰 注意:(volatile不具备原子性只有可见性)
在多线程操作同一个变量时 线程默认把变量保存到本线程的内层中 而不是直接在主内存中读写。
那么这就存在一个问题 当一个线程修改了变量的值 而另一个线程还在使用它本地内存中的变量值,这就导致了数据不一致的问题
volatile就能解决这个问题,当一个线程修改了主内存中的值时,则会通知其他线程修改本地内存的值。
注意一个细节 system.out.println会刷新内存空间 也就是说哪怕没用volatile 用了system.out.print 也能主动刷新内存空间
区别在于volatile主动通知其他线程,system.out.println主动获取将主内存中的值刷到本地
具体实现请看下面代码的区别
什么都不加的情况
import java.util.ArrayList;
import java.util.List;
public class ListAdd1 {
private static List list = new ArrayList();
public void add(){
list.add("bjsxt");
}
public int size(){
return list.size();
}
public static void main(String[] args) {
final ListAdd1 list1 = new ListAdd1();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
try {
for(int i = 0; i <10; i++){
list1.add();
System.out.println("当前线程:" + Thread.currentThread().getName() + "添加了一个元素..");
Thread.sleep(500);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
while(true){
if(list1.size() == 5){
System.out.println("当前线程收到通知:" + Thread.currentThread().getName() + " list size = 5 线程停止..");
throw new RuntimeException();
}
}
}
}, "t2");
t1.start();
t2.start();
}
}
volatile
import java.util.ArrayList;
import java.util.List;
public class ListAdd1 {
private volatile static List list = new ArrayList();
public void add(){
list.add("bjsxt");
}
public int size(){
return list.size();
}
public static void main(String[] args) {
final ListAdd1 list1 = new ListAdd1();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
try {
for(int i = 0; i <10; i++){
list1.add();
System.out.println("当前线程:" + Thread.currentThread().getName() + "添加了一个元素..");
Thread.sleep(500);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
while(true){
if(list1.size() == 5){
System.out.println("当前线程收到通知:" + Thread.currentThread().getName() + " list size = 5 线程停止..");
throw new RuntimeException();
}
}
}
}, "t2");
t1.start();
t2.start();
}
}
system.out.println
import java.util.ArrayList;
import java.util.List;
public class ListAdd1 {
private static List list = new ArrayList();
public void add(){
list.add("bjsxt");
}
public int size(){
return list.size();
}
public static void main(String[] args) {
final ListAdd1 list1 = new ListAdd1();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
try {
for(int i = 0; i <10; i++){
list1.add();
System.out.println("当前线程:" + Thread.currentThread().getName() + "添加了一个元素..");
Thread.sleep(500);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
try {
while(true){
Thread.sleep(500);
System.out.println();
if(list1.size() == 5){
System.out.println("当前线程收到通知:" + Thread.currentThread().getName() + " list size = 5 线程停止..");
throw new RuntimeException();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "t2");
t1.start();
t2.start();
}
}