JUC 简介

JUC 就是 java.util .concurrent 工具包的简称。这是一个处理线程的工具包,JDK 1.5 开始出现的。

进程与线程

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

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

总结来说

  • 进程:指在系统中正在运行的一个应用程序;程序一旦运行就是进程。进程是资源分配的最小单位。

  • 线程:系统分配处理器时间资源的基本单元,或者说进程之内独立执行的一个单元执行流。线程是程序执行的最小单位。

线程的状态

线程状态枚举类

进入查看Thread.State

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public enum State {
/**
* 尚未启动的线程的线程状态。
*/
NEW,

/**
* 可运行线程的线程状态
* 处于可运行状态的线程正在Java虚拟机中执行
* 但它可能正在等待操作系统的其他资源,如处理器。
*/
RUNNABLE,

/**
* 等待监视器锁定而阻塞的线程的线程状态
* 处于阻塞状态的线程正在等待监视器锁进入同步块/方法或调用后重新进入同步块/方法
* {@link Object#wait() Object.wait}.
*/
BLOCKED,

/**
* 等待线程的线程状态。线程处于等待状态
*
* 对象正在等待另一个线程调用
*/
WAITING,

/**
* 指定等待时间的线程状态。
* 线程由于调用其中之一而处于定时等待状态
*/
TIMED_WAITING,

/**
*
* 终止线程的线程状态
* 线程已经完成执行
*/
TERMINATED;
}
  • NEW:新创建了一个线程对象
  • RUNNABLE:线程对象创建后,其他线程调用了该对象的 start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取 CPU 的使用权
  • BLOCKED:阻塞状态是线程因为某种原因放弃 CPU 使用权,暂时停止运行
  • WAITING:线程在无限等待唤醒
  • TIMED_WAITING:线程在等待唤醒,但设置了时限
  • TERMINATED:总结

线程 5 种状态

  • 新建状态(New) :新创建了一个线程对象。

  • 就绪状态(Runnable) :线程对象创建后,其他线程调用了该对象的 start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取 CPU 的使用权。

  • 运行状态(Running): 就绪状态的线程获取了 CPU,执行程序代码。

  • 阻塞状态(Blocked): 阻塞状态是线程因为某种原因放弃 CPU 使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:

    • 等待阻塞:运行的线程执行 wait()方法,JVM 会把该线程放入等待池中。
    • 同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则 JVM 会把该线程放入锁池中。
    • 其他阻塞:运行的线程执行 sleep()或 join()方法,或者发出了 I/O 请求时,JVM 会把该线程置为阻塞状态。当 sleep()状态超时、join()等待线程终止或者超时、或者 I/O 处理完毕时,线程重新转入就绪状态。
  • 死亡状态(Dead):线程执行完了或者因异常退出了 run()方法,该线程结束生命周期。

wait/sleep 的区别

  1. sleep 是 Thread 的静态方法;wait 是 Object 的方法,任何对象实例都能调用。
  2. sleep 不会释放锁;wait 会释放锁,但调用它的前提是当前线程占有锁(即代码要在 synchronized 中)。
  3. 它们都可以被interrupted方法中断。
waitsleep
同步只能在同步上下文中调用 wait 方法,否则或抛出 llegalMonitorStateException 异常不需要在同步方法或同步块中调用
作用对象wait 方法定义在 Object 类中,作用于对象本身sleep 方法定义在 java.lang.Thread 中,作用于当前线程
释放锁资源
唤醒条件其他线程调用对象的 notify()或者 notifyAll()方法超时或者调用 interrupt()方法体
方法属性wait 是实例方法sleep 是静态方法

并行和串行

  • 串行:一次只能取得一个任务并执行这一个任务
  • 并行:可以同时通过多进程/多线程的方式取得多个任务,并以多进程或多线程的方式同时执行这些任务
  • 注意点:
    • 如果是单进程/单线程的并行,那么效率比串行更差
    • 如果只有单核 cpu,多进程并行并没有提高效率
    • 从任务队列上看,由于同时从队列中取得多个任务并执行,相当于将一个长任务队列变成了短队列

并发:

  • 并发是一种现象:同时运行多个程序或多个任务需要被处理的现象

  • 这些任务可能是并行执行的,也可能是串行执行的,和 CPU 核心数无关,是操作系统进程调度和 CPU 上下文切换达到的结果

  • 解决大并发的一个思路是将大任务分解成多个小任务:

    • 可能要使用一些数据结构来避免切分成多个小任务带来的问题

    • 可以多进程/多线程并行的方式去执行这些小任务达到高效率

    • 或者以单进程/单线程配合多路复用执行这些小任务来达到高效率