Thread 类的基本用法、Java 线程的几种状态

在Java中,Thread类是多线程编程的核心。

线程创建 (Thread Creation)
  • 创建线程主要有两种逻辑:继承Thread类或实现Runnable接口。
    • 方式1:继承 Thread 类,重写run()
// 自定义线程类继承Thread class MyThread extends Thread { // 重写run(),定义线程执行逻辑 @Override public void run() { System.out.println("子线程执行:" + Thread.currentThread().getName()); } } // 使用 public class Demo { public static void main(String[] args) { MyThread t = new MyThread(); t.start(); // 3. 调用start()启动线程(不能直接调用run()) } } 
  • 方式2:实现Runnable接口,传给Thread
// 实现Runnable接口 class MyRunnable implements Runnable { @Override public void run() { System.out.println("子线程执行:" + Thread.currentThread().getName()); } } // 使用 public class Demo { public static void main(String[] args) { // 把Runnable实例传给Thread Thread t = new Thread(new MyRunnable()); t.start(); // 启动线程 } } 
线程中断 (Thread Interruption)
  • 线程中断不是强制停止线程,而是一种协作机制,即给线程发一个“请停止”的信号。
  • void interrupt():标记线程为 “中断状态”
  • boolean isInterrupted():判断线程是否处于中断状态
  • 若线程在sleep/wait/join时被中断,会抛出InterruptedException,且中断状态会被清除
Thread t = new Thread(() -> { while (!Thread.currentThread().isInterrupted()) { // 检测中断状态 System.out.println("线程运行中..."); try { Thread.sleep(1000); } catch (InterruptedException e) { // 捕获中断异常后,中断状态会被清除,需手动终止循环 System.out.println("线程被中断"); Thread.currentThread().interrupt(); // 重新标记中断(可选) break; } } }); t.start(); // 主线程1秒后中断子线程 Thread.sleep(1000); t.interrupt(); 
线程等待 (Thread Join)
  • 有时主线程需要等待子线程执行完毕后再继续执行,这时可以使用join()。
  • t.join():当前线程会进入阻塞状态,直到线程t执行结束。
  • 带参数的 join(long millis):设置最大等待时间,如果超时线程还没结束,当前线程就不再等待。
Thread t = new Thread(() -> { System.out.println("子线程开始执行"); try { Thread.sleep(2000); } catch (InterruptedException e) {} System.out.println("子线程执行完毕"); }); t.start(); // 主线程等待t执行完(最多等3秒) t.join(3000); System.out.println("主线程继续执行"); 
线程休眠 (Thread Sleep)
  • static void sleep(long millis):让当前线程暂停指定时间(不会释放锁),抛出InterruptedException
System.out.println("开始休眠"); try { Thread.sleep(2000); // 当前线程休眠2秒 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("休眠结束"); 
获取线程实例 (Get Current Instance)
  • 在编写通用代码(尤其是 Runnable 中)时,常需要知道是谁在运行。
  • Thread.currentThread():返回代码当前正在执行的那个线程对象的引用。
  • 常用操作:获取线程 ID (getId())、获取线程名称 (getName()) 等。
// 获取当前线程(这里是main线程) Thread mainThread = Thread.currentThread(); System.out.println("当前线程名:" + mainThread.getName()); // 输出"main" // 子线程实例 Thread t = new Thread(() -> { Thread current = Thread.currentThread(); System.out.println("子线程名:" + current.getName()); // 输出"Thread-0" }); t.start(); 

Java线程的几种状态

线程状态一共有几种?
  • Java线程共有6种状态:
    • NEW (新建)
    • RUNNABLE (可运行)
    • BLOCKED (阻塞)
    • WAITING (等待)
    • TIMED_WAITING (超时等待)
    • TERMINATED (终止)
每种状态的含义与切换条件
  1. NEW (新建)
  • 含义:创建了线程对象(new Thread()),但尚未调用 start() 方法。
  • 切换:调用 start() 方法后,进入 RUNNABLE 状态。
  1. RUNNABLE (可运行)
  • 含义:Java 将操作系统中的“就绪(Ready)”和“运行中(Running)”两种状态统称为 RUNNABLE。处于该状态的线程可能正在 CPU 上执行,也可能正在等待操作系统分配时间片。
  • 切换:
    • 就绪 -> 运行:获得 CPU 时间片。
    • 运行 -> 就绪:CPU 时间片用完,或主动调用 Thread.yield()。
  1. BLOCKED (阻塞)
  • 含义:线程正在等待获取一个排他锁(如进入synchronized 代码块/方法),但该锁目前被其他线程持有。
  • 切换:
    • RUNNABLE -> BLOCKED:尝试进入 synchronized 区域失败。
    • BLOCKED -> RUNNABLE:其他线程释放锁,当前线程成功竞争到锁。
  1. WAITING (等待)
  • 含义:线程处于无限期的等待状态,不会被分配 CPU 时间,必须等待其他线程显式地唤醒。
  • 切换:
    • RUNNABLE -> WAITING:调用 Object.wait()(不带参数)、Thread.join()(不带参数)或 LockSupport.park()。
    • WAITING -> RUNNABLE:其他线程调用 Object.notify()、notifyAll() 或 LockSupport.unpark()。
  1. TIMED_WAITING (超时等待)
  • 含义:与 WAITING 类似,但在指定的时间后会自动唤醒,不需要其他线程显式唤醒。
  • 切换:
    • RUNNABLE -> TIMED_WAITING:调用 Thread.sleep(ms)、Object.wait(ms)、Thread.join(ms) 等带时间参数的方法。
    • TIMED_WAITING -> RUNNABLE:时间结束,或被提前唤醒(如 notify())。
  1. TERMINATED (终止)
  • 含义:线程已经执行完毕(run() 方法正常结束)或因异常退出了执行。
  • 切换:线程一旦进入此状态,生命周期结束,不可再次启动(再次调用 start() 会抛出异常)。

Read more

ROS 机器人工程师30 天突击学习计划(超详细・日更版)第一天 Linux

第 1 周:Linux + C++/Python + ROS 基础(Day1~7) Day1:Linux 终端命令(ROS 90% 操作都靠它) 上午 9:00–11:30 | 必背命令 查看日志 / 进程bash运行 top # 看CPU htop # 更直观 dmesg # 系统日志 文件操作bash运行 ls -la # 看所有文件 cd # 进入目录 pwd # 显示当前路径 mkdir -p # 递归创建文件夹 rm -rf # 删除(谨慎) cp -r # 复制文件夹 mv # 移动/

By Ne0inhk

2026年RAG技术路线图:基于DeepSeek与Neo4j知识图谱构建企业智能体系

RAG的演进:为何图检索增强生成(GraphRAG)将主导2026年 检索增强生成(RAG)自问世以来经历了深刻变革,2026年标志着其向图检索增强生成(GraphRAG)范式的关键性转变。这一演进源于传统平面向量型RAG在满足企业级复杂推理和可靠决策支持需求方面日益凸显的局限性。 这一转型的核心驱动力是从平面向量相似性向复杂关系推理的跨越。传统RAG依赖向量嵌入来衡量查询与文档片段的语义相似性,但这种方法无法捕捉企业决策至关重要的实体、概念与事件间的复杂关联。相比之下,GraphRAG将信息构建为包含节点(实体)和边(关系)的知识图谱,使模型能够遍历并推理这些关联——解锁了平面向量RAG无法实现的多跳推理和上下文关系理解能力。 GraphRAG还解决了传统RAG的两大长期痛点:上下文窗口限制和“中间信息丢失”问题。随着企业查询日益复杂,需要更大的上下文窗口来整合相关信息,但即便是最先进的大语言模型(LLM)也存在有限的上下文容量。GraphRAG通过将结构化知识存储在外部图数据库中解决了这一问题,允许模型按需检索最相关的节点和关系,而非将大量文本塞入上下文窗口。此外,“中间信息

By Ne0inhk

OpenClaw多智能体路由实战:飞书多机器人配置指南

文章目录 * 飞书重新安装问题 * 批量增加机器人 * 缺点 * 多个飞书机器人名称包含大小写的问题 * 多个Agent名称包含大小写的问题 目前我已经完成了OpenClaw的基本安装,但是在对话框只有一个,机器人也只绑定到主会话,一次只能处理一个消息。很多时候我在聊天窗口,说A任务,然后做了一半,又发了关于B任务的指令。一是每次发完消息,如果OpenClaw还在处理,剩下的消息要么进入队列、要么看不到(实际还在队列)。两个任务切来切去,感觉体验很不好。 要彻底解决这个问题,实现网上演示的那种对各Agent、每个对话机器人对应一个Agent,就需要用到多智能体路由技术。 实现的步骤如下: * 在飞书创建一个新的机器人 * 通过控制台创建新的智能体 * 按照指引将飞书配置上去 * 根据需要创建多个Agent和机器人,并对应配置上去(略) 飞书重新安装问题 明明我已经安装好了飞书,系统还是会提示我安装,否则就跳过了添加飞书这步。应该是系统Bug。这次安装的飞书位置在~/.openclaw/extensions/feishu,其实和~/.npm-globa

By Ne0inhk
【离散化 线段树 二分查找】3661可以被机器人摧毁的最大墙壁数目|2525

【离散化 线段树 二分查找】3661可以被机器人摧毁的最大墙壁数目|2525

本文涉及知识点 【C++】树状数组的使用、原理、封装类、样例 C++线段树 C++二分查找 3661. 可以被机器人摧毁的最大墙壁数目 一条无限长的直线上分布着一些机器人和墙壁。给你整数数组 robots ,distance 和 walls: robots[i] 是第 i 个机器人的位置。 distance[i] 是第 i 个机器人的子弹可以行进的 最大 距离。 walls[j] 是第 j 堵墙的位置。 每个机器人有 一颗 子弹,可以向左或向右发射,最远距离为 distance[i] 米。 子弹会摧毁其射程内路径上的每一堵墙。机器人是固定的障碍物:如果子弹在到达墙壁前击中另一个机器人,它会 立即 在该机器人处停止,无法继续前进。

By Ne0inhk