一、从操作系统角度理解程序、进程、线程
1.1 强烈推荐两篇博文,阐述的是Linux的程序、进程、线程的内存使用
Linux从程序到进程:www.cnblogs.com/vamei/archi…
Linux并发与同步:www.cnblogs.com/vamei/archi…
1.2 下图是Java中多线程在内存中的分布。建议先看上面两篇文章,写的很好所以直接推荐。

1.3 下图为Java的堆和栈中的对象存储位置

二、多线程原子性问题和内存可见性问题
2.1 Java内存模型与硬件模型

2.2 原子性问题和可见性问题

原子性问题,如图中的Race Condition那张图,count是一个共享的可变变量,左边的线程和右边的线程对count的操作都是count+1,这个操作分为三个步骤:读取count的值→count+1→存储count。左线程在读取了count的值为1后,正在做count+1时,右线程读取的count值仍然为1,右线程也做了count+1,但也是1+1,这样当两个线程做完三个步骤后,count是2并不是3,这样就引入了原子性问题。这样的三个步骤应该以原子的方式进行(即在这三个步骤运行过程中,不能有其他操作),这样的操作也叫复合操作。