进程是资源拥有的单位。线程是调度的最小单位。又称为轻进程。他只拥有进程中一些资源,这次资源对于这个线程来说是必不可少的。而所有的线程共享进程的资源。因此不同的线程之间可以共享一些数据变量。而进程则不可以,因为不同进程有不同过的进程控制块,分别处于不同的屋里地址空间里面。
每个线程都有自己的工作内存,也就是栈,如果从更底层的来说,相当于硬件的高速缓存,进程的一些公共资源常存放在堆中也就是主内存。不同线程之间的内容切换,首先要把各自的数据放到主内存中,才可以互相访问切换。
传统的操作系统中,没有引入线程,则并发是指进程。而对于进程的并发调度,也就是上下文切换,需要浪费极大地系统资源,例如cpu现场的保护,寄存器,内存地址的信息记录,调度算法的执行,以及进程状态的转换如从运行状态转换到阻塞状态,而且还要把把进程转到相应的队列里面。又因为有些进程只有一部分代码需要别的进程提供一些数据。如果因为这一点的东西需要数据而阻塞,然后要发生强大的进程切换,明显是浪费很多资源。
为此,在后来的操作系统中引入了线程概念。线程就是把一个进程分成好多部分,每一个部分都是一个线程,这所有的线程,共享进程的资源。当有一个线程需要别的进程提供数据,发生阻塞的时候,只有这个线程发生阻塞,其他的线程或许不需要这些数据也可以运行,因此只需要阻塞这个线程。进行单个线程切换,而整个进程则不需要切换,因此效率更高。单个线程的调度只需要保存一些必要的信息,如寄存器值,栈之子指针内容。线程切换,只需要更改一些寄存器的指针,如PC,pd等寄存器,当然这些是通过硬件实现的,效率是很快的,然后指向当前线程的代码开始地址处,当然对于源代码来说,本质上会经过编译程序和链接程序最终编程目标代码存放在内存之中的某一空白的内存地址处,并同时记录该内存地址的首地址,这些都是硬件级别的调用,只要要硬件的一些寄存器之类的东西转换一下就可以。速度相当快。并不需要什么进程调度算法,这些很慢的调度。因此引入线程,后系统的并发度会更高。
线程切换过程:
1.虚拟机启动之后,就进入了解释器的死循环,一直解释执行pc指针对应的java字节码。
2. 每个现在对应着一个stack,方面调用的时候,会在其上分配栈帧,由sp,fp等指针指向。
3. 线程调度,其实就是记录下当前线程的pc,sp,fp等指针,并将这几个指针(pc,sp,fp等,都是全局的)指向下一个将要执行的线程的相应位置。
4. 当恢复上述的几个指针之后,就切换回之前的线程了