内存模型:主内存 > 工作内存(线程私有内存) > cpu高速缓存
主内存与工作内存间 同步操作有:
1、lock (锁定主内存数据) ;unlock(解锁主内存数据)
2、read(读取主内存数据);load(将读取的主内存数据 载入到 工作内存中)
3、use(使用工作内存数据);assign(赋值工作内存数据)
4、store(储存工作内存数据);write(工作内存数据回写到主内存)
数据的使用按【1】【2】【3】【4】顺序执行,除了【3】外,其余操作不允许单独出现
备注:lock操作会将工作内存相同数据清空,unlock操作前会将工作内存数据store、write到主内存
原子性、可见性、有序性
上述操作均为原子性操作;
可见性:A线程修改数据,B线程立刻得知新值;
有序性:A线程内部操作均为有序,A观察B线程内部操作均为无序。
针对有序性有先行发生原则
程序次序规则:一个线程内,操作有序(顺序)
管程锁定规则:前一unlock操作先行后一lock操作【时间上】
volatile规则:volatile变量前一写操作先行后一读操作【时间上】
线程启动规则:Thread对象的start()方法先于此线程的每一操作
线程终止规则:线程的所有操作都先于此线程的终止
线程中断规则:对线程的interrupt()方法的调用先于被中断线程的代码检测到中断事件发生
对象终结规则:一个对象的初始化先于finalize()方法的开始
传递性:A先于B,B先于C,则A先于C
精华++
彩蛋
public class Test1 {
static volatile boolean fg = false;
static int i = 0;
public static void main(String[] args) throws InterruptedException {
/**
* 测试volatile 写操作先于读操作【时间上】
* 运用变量fg、i
*/
new Thread(() -> {
int i = 0;
while (i < 50) {
if (Test1.fg) {//与下面Thread相反
Test1.i++;
Test1.fg = !Test1.fg;
i++;
}
}
}).start();
new Thread(() -> {
int i = 0;
while (i < 50) {
if (!Test1.fg) {//与上面Thread相反
Test1.i++;
Test1.fg = !Test1.fg;
i++;
}
}
}).start();
Thread.sleep(1000);//保证两个子线程运行完毕
System.out.println(i);//始终是100,为线程安全
System.exit(0);
}
}