天天看点

万丈高楼平地起 -- 并发基础(一)

一:进程与线程

1.1 概念辨析

现代操作系统运行程序时就会创建一个进程,系统调用的最小操作单元就是线程,一个进程多以拥有多根线程。例如QQ音乐就是一个进程,进程中的播放、下载、收藏等操作都需要线程去完成

1.2 多线程意义

多线程等于快是多数人误区,多线程上下文切换以及线程创建销毁都需要资源消耗。使用多线程体现出快在多核处理器中就是将线程分配到不同CPU从而减少CPU闲置时间。单个CPU的某个时间节点只能运行一根线程,针对单核处理器的情况可以考虑在密集I/O的情况下使用多线程

二:线程状态

万丈高楼平地起 -- 并发基础(一)
万丈高楼平地起 -- 并发基础(一)

Thread内部枚举类State定义线程状态对象,具体含义如下所示:

状态名称 状态值
NEW 新建,线程类通过new关键字刚实例化时的状态
RUNNABLE 可执行,线程调用start()后等待CPU资源的状态
BLOCKED 阻塞,等待线程锁
WAITING 阻塞,等待特定方法执行如notify()
TIMED_WAITING 阻塞,如sleep()后等待时间到达
TERMINATED 终止、销毁

三:线程优先级

万丈高楼平地起 -- 并发基础(一)

线程优先级Thread类中提供属性priority及其相关方法get/set设定,同时提供三个常量表示优先级等级。注意以下几点:

  1. Java中线程优先级是伪优先级,不能决定线程执行顺序

  2. 线程优先级范围为1-10,默认线程优先级为5
  3. 子线程优先级与父线程默认保持一致

四:守护线程

万丈高楼平地起 -- 并发基础(一)
  1. Thread中使用属性Daemon标记守护线程,线程启动前使用set方法设置
  2. 子线程是否为守护线程与父线程保持一致
  3. 当所有非守护线程结束后守护线程立即终止退出,这里考虑下finally执行

五:线程阻塞

5.1 sleep
万丈高楼平地起 -- 并发基础(一)
  1. 线程状态从RUNNING改变到TIMED_WAITING,陷入等待沉睡
  2. 该阻塞状态下线程不会释放CPU以及锁资源
  3. 该方法是中断敏感异常方法
5.2 wait
万丈高楼平地起 -- 并发基础(一)
  1. 线程状态由RUNNING改变为WAITING,等待特定唤醒
  2. 执行该方法线程必须拥有对象监视器,通俗点就是
  3. 执行该方法线程释放锁资源,notify/notifyAll唤醒后重新争取CPU资源
  4. 默认无参执行wait(0)无限制等待,重载可以限定等待时长
  5. 切记一点该方法不是线程实例调用,Object提供方法,释放线程为当前线程

5.3 yield
万丈高楼平地起 -- 并发基础(一)

Object提供,向调度程序提示恐龙让梨,我愿意退后一步放弃当前使用的处理器。但是调度程序可能会尊老爱幼,忽略它的申请。也就是

不确定性

六:线程中断

6.1 中断标记
万丈高楼平地起 -- 并发基础(一)

看清楚interrupt0()方法后注释,仅仅只是整个标记,该方法不影响线程运行。但是遇到中断检查可以抛出中断异常InterruptedException,例如sleep()

6.2 检查中断
万丈高楼平地起 -- 并发基础(一)
万丈高楼平地起 -- 并发基础(一)

两个检查中断标记的方法都调用本地方法isInterrupted实现,但是注意咯:

interrupted()参数传递true,isInterrupted()参数传递false,代表是否祛除中断标记
           
万丈高楼平地起 -- 并发基础(一)

七:线程串行

万丈高楼平地起 -- 并发基础(一)
  1. 线程A中执行线程B.join()表示先让B线程执行后再执行A
  2. join()参数可限制执行时长,超时未执行完则需要竞争CPU资源

继续阅读