JUC-线程基础(2)

50 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

线程上下文切换

因为以下一些原因导致cpu不再执行当前的线程,转而执行另一个线程的代码

  • 线程的cpu时间片用完
  • 垃圾回收
  • 有更高优先级的线程需要运行
  • 线程自己调用了sleep、yield、wait、join、park、synchronized、.lock等方法

当发生上下文切换时,需要由操作系统保存当前线程的状态,并恢复另一个线程的状态,Java中对应的概念就是程序计数器(Program Counter Register)

  • 状态包括程序计数器、虚拟机栈中每个栈帧的信息,如局部变量、操作数栈、返回地址等
  • 上下文频繁切换会导致性能下降

线程组

每个Thread必然存在于⼀个ThreadGroup中,Thread不能独⽴于ThreadGroup存在。

如果在new Thread时没有显式指定线程组,那么默认将⽗线程 (当前执⾏new Thread的线程)线程组设置为⾃⼰的线程组。

ThreadGroup是⼀个标准的向下引⽤的树状结构,这样设计的原因是防⽌"上级"线程被"下级"线程引⽤⽽⽆法有效地被GC回收。

线程优先级

Java中线程优先级可以指定,范围是1~10,默认是5

Java只是给操作系统⼀个优先级的建议,线程最终在操作系统的优先级是多少还是由操作系统决定。

守护线程

默认情况下,Java 进程需要等待所有线程都运行结束,才会结束。有一种特殊的线程叫做守护线程,当其它非守护线程运行结束了,即使守护线程的代码没有执行完,也会强制结束。

守护线程默认的优先级比较低

log.debug("开始运行...");
Thread t1 = new Thread(() -> {
     log.debug("开始运行...");
     sleep(2);
     log.debug("运行结束...");
}, "daemon");

t1.setDaemon(true); // 设置该线程为守护线程
t1.start();

sleep(1);
log.debug("运行结束...");

注意:

  • 垃圾回收器、JIT线程就是一种守护线程