线程---操作系统内存模型、java内存模型、线程可见性问题、 指令重排序、Happens-before规则

送分小仙女□ 提交于 2020-02-01 14:38:43

操作系统内存模型

在这里插入图片描述

  • L1、L2是每个CPU自己的高速缓存
  • L3是CPU之间共享的缓存
  • L1和L2的缓存命中率均约为80%
  • 达到L3缓存数据占比4%左右

Java内存模型

在这里插入图片描述

  • 每个线程有自己的工作内存
  • 工作内存包含线程本地局部变量和主内存的副本拷贝
  • 线程之间的共享变量通过主内存在各线程间同步

线程可见性问题

package day0201;

public class ThreadSafe {
	private static int a=0;
	
	public static void main(String[] args) throws Exception {
		Thread threadA = new Thread(() ->{
			System.out.println("threadA"+Thread.currentThread().getName()+"a="+a);
			a=1;
			System.out.println("threadA"+Thread.currentThread().getName()+"a="+a);
		});
		
		Thread threadB = new Thread(()->{
			System.out.println("threadB"+Thread.currentThread().getName()+"a="+a);
			a=1;
			System.out.println("threadB"+Thread.currentThread().getName()+"a="+a);
		});
		
		threadA.start();
		threadB.start();
		
		threadA.join();
		threadB.join();
		
		System.out.println("a="+a);
	}
}

结果:
在这里插入图片描述
在这里插入图片描述

  • 线程工作内存的值写入到主内存,另一个线程从主内存读取到这个值
  • 由于可见性问题,另一个线程拿到的值并不是实时的

指令重排序问题

package day0201;

public class ThreadRecordering {
	private static int a=0;
	private static int b=0;
	private static int x=0;
	private static int y=0;
	
	public static void main(String[] args) throws Exception {
		Thread threadA = new Thread(()->{
			b=1;
			x=a;
		});
		Thread threadB = new Thread(()->{
			a=1;
			y=b;
		});
		threadA.start();
		threadB.start();
		
		threadA.join();
		threadB.join();
		
		System.out.println("x="+x+";y="+y);
	}
}

结果,x=0;y=1或x=1;y=0或x=0;y=0或x=1;y=1(都有可能)
在这里插入图片描述
重排序可能发生再编译器,也可能发生再处理器
在这里插入图片描述

重排序发生的条件

违反了Happens-before规则,就会发生指令重排序

Happens-before规则

  • 程序次序规则:在程序中若操作A先于操作B发生,那么线程中操作A也先于操作B发生
  • 对象终结规则:一个对象的构造函数的完成先行发生于其finalize()方法
  • 锁规则:对同一个锁,加锁操作先行发生于解锁操作
  • 传递规则:如果操作A先行发生于操作B,而操作B又先行发生于操作C,则操作A先行发生于操作C
  • volatile变量规则:对一个volatile变量的写操作先行发生于对这个变量的读操作
  • 线程启动规则:Thread对象的start()方法先行发生于此线程中的每个指令操作
  • 线程中断规则:一个线程对另一个线程调用interrupt()方法,先行发生于被中断线程检测到中断时间
  • 线程结束规则:线程中所有的操作都先行发生于线程的终止时,如线程结束,Thread.join()返回
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!