下述列举的规则,总结了一个线程的写对其他线程的读是可见的情况!
1:synchronized/ReentrantLock
public class Test1 {
static int x=0;
public static void main(String[] args) throws InterruptedException {
Object lock=new Object();
new Thread(()->{
synchronized (lock){
x=5;
}
}).start();
new Thread(()->{
synchronized (lock){
System.out.println(x);
}
}).start();
}
}
synchronized是java中的同步技术,可以保证线程安全三大特性(可见,有序,原子),因为给线程加锁,一次只能一个线程拥有锁,且结束同步代码块会自动解锁(解锁后会将线程本地内存刷新到主内存中)。ReentrantLock是同样的原理
volatile
public class Test1 {
static volatile int x=0;
public static void main(String[] args) throws InterruptedException {
Object lock=new Object();
new Thread(()->{
x=5;
}).start();
new Thread(()->{
System.out.println(x);
}).start();
}
}
这里当然是volatile的原理所决定的(读写屏障)
start
public class Test1 {
static volatile int x=0;
public static void main(String[] args) throws InterruptedException {
x=5;
new Thread(()->{
System.out.println(x);
}).start();
}
}
这里当然线程启动之后对于之前已经在主存中该变过的数据是可见的!
当然这里对应就是线程的结束后也会将私有本地内存中的数据刷新到主内存中去,例如t1线程调用join