线程
2026年3月18日大约 2 分钟
线程
线程使用
线程原理
栈与栈帧
当线程启动后,JVM会为线程分配栈内存。
- 栈帧:每个方法调用都会创建一个栈帧。
- 每个线程只能有一个活动栈帧,对应当前执行的方法。
线程上下文切换
当因为某些原因,cpu不再执行当前线程,而是切换执行另一个线程的代码。可能的原因包括:
- 线程的CPU时间片用完。
- 垃圾回收:垃圾回收会暂停所有线程,交由垃圾回收线程执行。
- 有更高优先级的线程需要执行。
- 线程进入等待状态:如调用了
wait()、sleep()、join()、park()等方法。
当线程上下文切换时,CPU需要保存当前线程的状态,并加载新线程的状态。
这是一个比较耗时的操作,因此频繁的线程切换会导致性能下降。
程序计数器
记住下一条 JVM 指令的执行地址,是线程私有的。
常用方法
start()与run()
start():启动线程,调用后会创建一个新的线程来执行run()方法中的代码。run():线程执行的入口方法,包含线程要执行的代码。
警告
注意:直接调用run()方法不会启动新线程,而是在当前线程中执行。
sleep()与yield()
sleep(long millis):让当前线程休眠指定的时间,单位为毫秒。线程处于TIMED_WAITING状态,不会占用CPU资源。yield():让当前线程让出CPU执行权。线程处于RUNNABLE状态。具体执行由 系统任务调度器决定。
相关信息
在循环中使用Thread.sleep(),可以让线程暂停一段时间,减少CPU占用率。
线程优先级
- 设置线程优先级:
setPriority(int newPriority),参数范围为1(最低)到10(最高)。 - Java线程有10个优先级,范围从1(最低)到10(最高)。默认优先级为5。
注意
和yield()一样,线程优先级只是一个提示,具体执行顺序由系统任务调度器决定。
join()
join():等待线程执行完成。调用join()方法的线程会被阻塞,直到被调用的线程执行完毕。join(long millis):等待指定时间,如果线程在指定时间内执行完毕,则继续执行;超时则不再等待。
interrupt()
interrupt():中断线程。isInterrupted():检查线程是否被中断。
相关信息
正常运行被打断,打断标记会为true;
处于wait()、sleep()、join()等阻塞状态被打断,会抛出InterruptedException,打断标记会被清除为false。
LockSupport.park()
park():阻塞当前线程,直到被其他线程调用unpark()方法或被中断。
注意
使用interrupt()打断park()线程时,但打断标记不会被清除。
- 因此会导致再次调用
park()时,无法进入阻塞状态。