Java 线程类
最后修改时间:2025 年 4 月 13 日
java.lang.Thread
类是 Java 多线程能力的基础。它代表 Java 程序中的一个执行线程。线程允许并发执行代码段,从而实现高效的资源利用。
线程共享相同的内存空间,但独立执行。Thread 类提供了创建、控制和管理线程的方法。理解线程对于编写响应迅速且高效的 Java 应用程序至关重要。
线程类方法
Thread 类提供了控制线程执行和查询线程状态的方法。主要方法包括 start
、run
、sleep
、join
和 interrupt
。这些方法管理线程生命周期和同步。
public class Thread implements Runnable { public Thread() {...} public Thread(Runnable target) {...} public void start() {...} public void run() {...} public static void sleep(long millis) throws InterruptedException {...} public final void join() throws InterruptedException {...} public void interrupt() {...} public static Thread currentThread() {...} public final boolean isAlive() {...} public final void setPriority(int priority) {...} }
上面的代码展示了 Thread 类的关键方法。这些方法支持线程创建、执行控制和状态监控。可以通过扩展 Thread 或实现 Runnable 来创建线程。
通过扩展 Thread 类创建线程
创建线程的最简单方法是扩展 Thread 类并重写其 run
方法。start
方法启动线程执行。这种方法简单明了,但限制了继承。
package com.zetcode; class MyThread extends Thread { @Override public void run() { for (int i = 0; i < 5; i++) { System.out.println("Thread running: " + i); try { Thread.sleep(500); // Pause for 500ms } catch (InterruptedException e) { System.out.println("Thread interrupted"); return; } } } } void main() { MyThread thread = new MyThread(); thread.start(); // Start the thread // Main thread continues execution for (int i = 0; i < 3; i++) { System.out.println("Main thread: " + i); try { Thread.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } } }
此示例演示了通过扩展 Thread 创建线程。主线程和 MyThread 并发执行。输出显示交错执行。Thread.sleep 暂停执行,不消耗 CPU 资源。
通过实现 Runnable 创建线程
更灵活的方法是实现 Runnable 接口。这允许类在仍然可以作为线程执行的同时,扩展另一个类。Runnable 对象被传递给 Thread 构造函数。
package com.zetcode; class Task implements Runnable { @Override public void run() { for (int i = 0; i < 5; i++) { System.out.println("Task executing: " + i); try { Thread.sleep(400); } catch (InterruptedException e) { System.out.println("Task interrupted"); return; } } } } void main() { Task task = new Task(); Thread thread = new Thread(task); thread.start(); // Main thread work for (int i = 0; i < 4; i++) { System.out.println("Main thread working"); try { Thread.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } } }
此示例显示了使用 Runnable 创建线程。Task 类实现 Runnable 并在其 run 方法中定义工作。使用 Task 实例创建一个 Thread 对象。两种方法都实现了类似的结果,但 Runnable 更灵活。
线程休眠和中断
sleep
方法将线程执行暂停指定的时间。可以使用 interrupt
中断线程,该方法发送中断信号。正确的中断处理使线程更具响应性。
package com.zetcode; class Worker implements Runnable { @Override public void run() { try { for (int i = 0; i < 10; i++) { System.out.println("Working... " + i); if (Thread.interrupted()) { System.out.println("Thread was interrupted"); return; } Thread.sleep(500); } } catch (InterruptedException e) { System.out.println("Thread interrupted during sleep"); return; } } } void main() throws InterruptedException { Thread worker = new Thread(new Worker()); worker.start(); Thread.sleep(2000); // Let worker run for 2 seconds worker.interrupt(); // Interrupt the worker worker.join(); // Wait for worker to finish System.out.println("Main thread done"); }
此示例演示了线程中断。Worker 使用 Thread.interrupted
检查中断并处理 InterruptedException。主线程在 2 秒后中断 Worker。正确的中断处理确保干净的线程终止。
线程加入
join
方法允许一个线程等待另一个线程完成。当线程执行顺序很重要或者需要合并结果时,这非常有用。Join 可以指定最大等待时间。
package com.zetcode; class Calculator implements Runnable { private int result; @Override public void run() { result = 0; for (int i = 1; i <= 100; i++) { result += i; try { Thread.sleep(10); } catch (InterruptedException e) { System.out.println("Calculation interrupted"); return; } } } public int getResult() { return result; } } void main() throws InterruptedException { Calculator calc = new Calculator(); Thread calcThread = new Thread(calc); calcThread.start(); System.out.println("Waiting for calculation to complete..."); calcThread.join(); // Wait for calculation to finish System.out.println("Result: " + calc.getResult()); }
此示例显示线程加入。主线程使用 join
等待 Calculator 完成。如果没有加入,main 可能会在计算完成之前访问结果。加入确保适当的同步。
线程优先级
线程优先级向调度程序提示线程的重要性。优先级范围从 1 (MIN_PRIORITY) 到 10 (MAX_PRIORITY)。默认值为 5 (NORM_PRIORITY)。优先级较高的线程获得更多的 CPU 时间,但不保证首先运行。
package com.zetcode; class Counter implements Runnable { private String name; public Counter(String name) { this.name = name; } @Override public void run() { for (int i = 0; i < 5; i++) { System.out.println(name + ": " + i); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } } } } void main() { Thread lowPriority = new Thread(new Counter("Low")); Thread highPriority = new Thread(new Counter("High")); lowPriority.setPriority(Thread.MIN_PRIORITY); highPriority.setPriority(Thread.MAX_PRIORITY); highPriority.start(); lowPriority.start(); }
此示例演示了线程优先级。高优先级线程通常在低优先级线程之前执行,但这不能保证。线程调度取决于 JVM 和操作系统实现。
线程同步
线程同步防止并发访问共享资源。synchronized
关键字创建了每次只能由一个线程进入的临界区。这可以防止竞争条件和数据损坏。
package com.zetcode; class Counter { private int count = 0; public synchronized void increment() { count++; } public synchronized int getCount() { return count; } } class Incrementer implements Runnable { private Counter counter; public Incrementer(Counter counter) { this.counter = counter; } @Override public void run() { for (int i = 0; i < 10000; i++) { counter.increment(); } } } void main() throws InterruptedException { Counter counter = new Counter(); Thread t1 = new Thread(new Incrementer(counter)); Thread t2 = new Thread(new Incrementer(counter)); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println("Final count: " + counter.getCount()); }
此示例显示线程同步。如果没有 synchronized 方法,由于竞争条件,最终计数可能小于 20000。同步确保对 count 变量的原子访问。结果始终为 20000。
来源
本教程通过实际示例介绍了基本的 Thread 类概念。理解线程对于编写并发 Java 应用程序至关重要。正确的线程管理确保高效的资源利用和响应能力。
作者
列出所有Java教程。