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教程。