什么是进程?
操作系统会以进程为单位,分配系统资源(CPU时间片、内存等资源),进程是资源分配的最小单位。
当一个程序被运行,从磁盘加载这个程序的代码至内存,这时就开启了一个进程。
什么是线程?
线程,有时被称为轻量级进程,是操作系统调度(CPU调度)执行的最小单位。
线程是进程中的实体,一个进程可以拥有多个线程,一个线程必须有一个父进程。
一个线程就是一个指令流,将指令流中的一条条指令以一定的顺序交给 CPU 执行 。
线程的生命周期
以Java语言为例线程的状态有:
1.在Java中使用new Thread()创建一个线程,然后调用statr0方法进行Java层的线程的启动
2.start0方法是一个本地方法(native),底层由c/c++语言实现,通过JDK源码可以得知调用了JVM(Java虚拟机)中的JVM_StartThread方法进行线程创建和启动(JVM层面)
3.用 new JavaThread(&thread entry, sz) 进行线程的创建,并根据不同的操作系统平台调用对应的 os::create thread 方法进行线程创建**(真正创建一个线程!**创建Java线程对应的内核线程)
4.新创建的线程状态为 lnitialized(初始化状态),调用了sync->wait() 的方法进行等待(先阻塞!!!),等到被唤醒才继续执行 thread->run()
5.调用 Thread::start(native thread) 方法进行线程启动,此时将线程状态设RUNNABLE,接着调用 os::start_thread(thread),根据不同的操作系统选择不同的线程启动方式
以linux为例os_linux.cpp,在实现中调用了pthread_create来创建线程
6.线程启动之后状态设置为RUNNABLE,并唤醒第4步中等待的线程,接着执行 thread->run() 的方法
7.JavaThread::run()方法会回调第1步new Thread中复写的run()方法。
总结来说:在操作系统层面的线程会先进行初始化后进入wait状态,直到JVM层面的线程绑定为runnable状态再通过回调Java层的run()方法,涉及到用户态和内核态的转换,所以Java的线程创建和销毁是十分重要的操作,所以我们引入了线程池(Thread poll)来实现线程的复用,减少了创建销毁线程消耗的操作系统资源