我有两个线程,A线程负责把list.add()执行10次,B线程在list.size()超过5的时候抛异常退出。
下面是代码。
package com.lock;import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;/**
* Create by @author Henry on 2018/5/4
*/
public class NoWait {
static volatile ArrayList list = new ArrayList();
public static void main(String[] args) throws InterruptedException { ThreadA a = new ThreadA(list);
a.setName("A");
a.start(); ThreadB b = new ThreadB(list);
b.setName("B");
b.start(); Thread.sleep(10000);
System.out.println("A is " + a.isAlive());
System.out.println("B is " + b.isAlive());
}
}class ThreadA extends Thread{
private ArrayList list;
public ThreadA(ArrayList list){
this.list = list;
} @Override
public void run(){
try{
for (int i = 0; i < 10; i++) {
list.add(i);
System.out.println("=====================================添加了 "+(i+1)+" 个元素");
Thread.sleep(100);
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("A finished");
}
}class ThreadB extends Thread{
String s;
private ArrayList list;
public ThreadB(ArrayList list){
this.list = list;
} @Override
public void run(){
try{
while(true){
//s += list.size();
//System.out.println(list.size());
if(list.size() > 5){
System.out.println(">5 now, B gonne quit");
throw new InterruptedException();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
这是结果
这里我的理解是,B线程一只访问的是B线程私有内存上的list,因此list.size()一直没变过。所以不会退出。但是当我去掉这两行中随便一行的注释时,就会出现正常退出,既当A线程的list.add()执行了5次以上时,B线程随时可能退出。我想请问一下,这两行代码都是怎么起作用的。
下面是代码。
package com.lock;import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;/**
* Create by @author Henry on 2018/5/4
*/
public class NoWait {
static volatile ArrayList list = new ArrayList();
public static void main(String[] args) throws InterruptedException { ThreadA a = new ThreadA(list);
a.setName("A");
a.start(); ThreadB b = new ThreadB(list);
b.setName("B");
b.start(); Thread.sleep(10000);
System.out.println("A is " + a.isAlive());
System.out.println("B is " + b.isAlive());
}
}class ThreadA extends Thread{
private ArrayList list;
public ThreadA(ArrayList list){
this.list = list;
} @Override
public void run(){
try{
for (int i = 0; i < 10; i++) {
list.add(i);
System.out.println("=====================================添加了 "+(i+1)+" 个元素");
Thread.sleep(100);
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("A finished");
}
}class ThreadB extends Thread{
String s;
private ArrayList list;
public ThreadB(ArrayList list){
this.list = list;
} @Override
public void run(){
try{
while(true){
//s += list.size();
//System.out.println(list.size());
if(list.size() > 5){
System.out.println(">5 now, B gonne quit");
throw new InterruptedException();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
这是结果
这里我的理解是,B线程一只访问的是B线程私有内存上的list,因此list.size()一直没变过。所以不会退出。但是当我去掉这两行中随便一行的注释时,就会出现正常退出,既当A线程的list.add()执行了5次以上时,B线程随时可能退出。我想请问一下,这两行代码都是怎么起作用的。
List list = Collections.synchronizedList(new ArrayList(...));
这段代码的重点在于你加了volatile关键字,加入volatile关键字时,会多出一个lock前缀指令
会帮你屏障内存,内存屏障会提供3个功能:1)它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成;2)它会强制将对缓存的修改操作立即写入主存;3)如果是写操作,它会导致其他CPU中对应的缓存行无效。