多线程基础概念

概念:

进程: 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。

线程: 线程(thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。线程是独立调度和分派的基本单位。线程分为用户线程和内核线程。

多线程: 多线程是多任务的一种特别的形式,但多线程使用了更小的资源开销。多线程能满足程序员编写高效率的程序来达到充分利用 CPU 的目的。

并行: 多个cpu实例或者多台机器同时执行一段处理逻辑,是真正的同时运行。

并发: 使用CPU调度算法,使用户看起来在同时运行,其实并不是在同时运行。并发一般发生在对系统中的公用资源操作时。

线程安全: 指的是希望多线程的执行顺序对执行结果没有影响,用户只需要关心CPU及其他资源是否够用即可。反之,如果不同的执行顺序导致不同的执行结果,那么就说是线程不安全的。

同步: 指通过人为干预的情况下达到线程安全的程度。

进程VS线程:

  1. 地址空间和其它资源:进程间相互独立,同一进程的各线程间共享。某进程内的线程在其它进程不可见。
  2. 通信:通信方式不同,线程间可以直接读写进程数据段(如全局变量)来进行通信——需要进程同步和互斥手段的辅助,以保证数据的一致性。
  3. 调度和切换:线程上下文切换比进程上下文切换要快得多。
  4. 在多线程OS中,进程不是一个可执行的实体。

线程的状态:

Java 给多线程编程提供了内置的支持。

线程状态切换

新建状态:一个新产生的线程从新状态开始了它的生命周期。它保持这个状态直到程序start这个线程。此过程线程并未执行。

就绪状态:表明线程可以运行,但不是真的在运行,此状态下需要获取cpu才能运行。调用线程的star方法、获取到对象的锁,阻塞状态解除、cpu时间片用完,调用yield()方法、jvm中断此线程。

运行状态:线程在阻塞状态获取到cpu使用权,开始实际执行。此状态线程进入run()方法执行方法体。

阻塞状态:线程放弃了cpu,调用wait(),sleep(),或同步锁,同步代码块时,失去了所占用的资源,由运行态进入阻塞态,线程将会进入阻塞队列。执行了wait()方法后使线程进入到等待阻塞状态、在进入synchronized代码块,获取同步锁失败时进入同步阻塞、当调用sleep(),join(),或io时进入其它阻塞队列,等待sleep()结束,join()等待其它线程结束,io结束时继续进入就绪状态。

死亡状态:线程结束运行后就进入死亡状态。死亡后不会再进入新生态,调用start()方法会报错。通常run()方法运行结束时死亡,或一个未捕获的异常导致猝死。

超时等待:处于这种状态的线程不会被分配CPU执行时间,不过无须无限期等待被其他线程显示地唤醒,在达到一定时间后它们会自动唤醒。


队列:

等待队列:线程wait()后进入等待队列,等待被其它线程使用notify()或notifyAll()唤醒。

同步队列:线程被唤醒后,进入同步同步队列,在此队列中,互相竞争对象的锁,当获取到对象的锁之后就进入了就绪状态等待获取cpu时间片运行。


线程优先级:

每一个 Java 线程都有一个优先级,这样有助于操作系统确定线程的调度顺序。

Java 线程的优先级是一个整数,其取值范围是 1 (Thread.MIN_PRIORITY ) - 10 (Thread.MAX_PRIORITY )。

默认情况下,每一个线程都会分配一个优先级 NORM_PRIORITY(5)。

具有较高优先级的线程对程序更重要,并且应该在低优先级的线程之前分配处理器资源。但是,线程优先级不能保证线程执行的顺序,而且非常依赖于平台。


参考资料 & 鸣谢