线程
提到并发自然会想到“线程”,那说到线程,“进程”一词也不得不被拿来叙述一番。对于一个Java程序员来说,这两概念是肯定是要熟烂于心的。
进程:是代码在数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,
线程
:则是进程的一个执行路径,一个进程至少拥有一个线程
,进程中的多个线程共享进程的资源。
操作系统在分配资源时,是把资源分配给进程的,但是cpu资源比较特殊,它是分配到每一个线程的,因为真正占用cpu运行的是线程,所以也说线程是cpu分配的基本单位。
在Java中,我们启动main方法时也就是程序的入口,其实就启动了一个JVM的进程,而main方法所在的线程就是这个进程的其中一个线程,也称主线程。
来个图了解一下:
由图可以看出:一个进程有多个线程,多个线程共享进程中的堆和方法区的资源,但每个线程有自己的程序计数器和栈区域。
程序计数器是一块内存区域,是用来记录线程当前要执行的指令地址,线程是cpu执行的基本单元,而cpu一般是使用时间片轮转的方式来让线程轮询占用,所以当前线程cpu时间用片完之后,要让出cpu,等下次轮到自己的时候再执行。那么当前线程是怎么知道之前执行到哪一步了呢?其实程序计数器就是为了记住该线程让出cpu时的执行地址的,等到再次分配到cpu的时间片时,就可以从自己私有的计数器指定的地址继续执行任务。另外要注的是,如果执行的是native方法,那么pc计数器记录的是undefined地址,只有执行Java代码时,pc计数器记录的才是下一条指令地址。
另外每个线程都有自己的栈资源,用于存储该线程的局部变量,这些局部变量是该线程私有的,其他线程是访问不了的,除此之外,栈还用来存放线程的调用栈帧。
堆是一个进程中最大的一个内存区域,堆是被进程中的所有线程共享的,是进程创建时分配的,堆里面主要存放这个使用new操作创建的对象实例。
方法区则是用来存放JVM加载的类,常量及静态变量等信息,也是线程共享的。
备注:最近读了一本书,霍陆续 薛宾田 两位老师写的《Java并发编程之美》,内容比较丰富,这里小编借此分享出来并加上一些自己的理解,同各位一起交流学习