Java线程基础概念
Java线程是程序执行的最小单元,是操作系统的线程在Java中的抽象,线程与进程的区别在于,进程是资源分配的基本单位,而线程是CPU调度的基本单位,一个进程可以包含多个线程,它们共享进程的内存空间和资源,这提高了程序的执行效率但也带来了线程同步的问题,在Java中,线程通过java.lang.Thread类实现,每个线程都有自己独立的程序计数器、虚拟机栈和本地方法栈,但堆区和方法区是所有线程共享的。

线程的创建方式
Java中创建线程主要有三种方式:
-
继承Thread类:通过自定义类继承
Thread并重写run()方法,创建实例后调用start()启动线程。class MyThread extends Thread { @Override public void run() { System.out.println("Thread running"); } } MyThread thread = new MyThread(); thread.start();这种方式简单但灵活性低,因为Java不支持多继承,继承Thread类后无法再继承其他类。
-
实现Runnable接口:自定义类实现
Runnable接口的run()方法,将实例作为参数传递给Thread类启动线程。class MyRunnable implements Runnable { @Override public void run() { System.out.println("Runnable running"); } } Thread thread = new Thread(new MyRunnable()); thread.start();这是更推荐的方式,避免了单继承限制,且线程与任务分离,便于解耦。
-
实现Callable接口:通过
Callable接口可以定义带返回值的任务,配合FutureTask获取执行结果。
import java.util.concurrent.*; class MyCallable implements Callable<String> { @Override public String call() throws Exception { return "Callable result"; } } FutureTask<String> futureTask = new FutureTask<>(new MyCallable()); Thread thread = new Thread(futureTask); thread.start(); System.out.println(futureTask.get()); // 获取返回结果Callable支持泛型返回值,适合需要线程返回结果的场景。
线程的生命周期
Java线程的生命周期包括六个状态:
- 新建(New):线程被创建但未启动,此时
thread.getState()返回NEW。 - 可运行(Runnable):调用
start()后,线程进入就绪状态,等待CPU调度,可能包含运行中状态。 - 阻塞(Blocked):线程等待获取锁(如
synchronized代码块),暂时放弃CPU。 - 等待(Waiting):线程进入无限等待状态,需通过
notify()或interrupt()唤醒,例如调用Object.wait()或Thread.join()。 - 超时等待(Timed Waiting):在指定时间内等待,超时后自动唤醒,例如
Thread.sleep()或Lock.tryLock()。 - 终止(Terminated):线程执行完成或因异常退出,状态不可逆转。
线程状态可通过Thread.getState()方法查看,理解生命周期有助于排查线程死锁、阻塞等问题。
线程同步与锁机制
多线程共享资源时,需要通过同步机制避免数据不一致问题,Java提供了多种同步方式:
-
synchronized关键字:可以修饰方法或代码块,确保同一时间只有一个线程执行同步代码。
- 修饰实例方法:锁为当前对象实例。
- 修饰静态方法:锁为当前类的Class对象。
- 修饰代码块:可指定锁对象,灵活性更高。
-
Lock接口:
java.util.concurrent.locks.Lock提供更灵活的锁机制,支持尝试获取锁(tryLock())、公平锁等。
ReentrantLock lock = new ReentrantLock(); lock.lock(); try { // 同步代码 } finally { lock.unlock(); // 必须在finally中释放锁 } -
volatile关键字:确保变量的可见性,禁止指令重排序,但不保证原子性,适用于一个线程写、多个线程读的场景。
-
原子类:如
AtomicInteger,通过CAS(Compare-And-Swap)操作保证原子性,避免synchronized的性能开销。
线程池的使用
线程池是管理线程的重要工具,通过复用线程减少创建和销毁的开销,提高系统稳定性,Java提供了Executor框架,核心接口包括Executor、ExecutorService和ThreadPoolExecutor。
- 创建线程池:推荐使用
Executors工厂类,如Executors.newFixedThreadPool(5)创建固定大小线程池,或Executors.newCachedThreadPool()创建可缓存线程池。 - 执行任务:通过
execute(Runnable)提交无返回值任务,或submit(Callable)提交有返回值任务。 - 关闭线程池:调用
shutdown()停止接受新任务并等待线程执行完成,或shutdownNow()立即停止所有任务。
线程池参数需合理配置,避免线程过多导致资源耗尽,或线程过少无法充分利用CPU。
Java线程是并发编程的核心,掌握线程的创建、生命周期、同步机制和线程池使用是开发高性能应用的基础,在实际开发中,需根据场景选择合适的同步方式,合理设计线程池,并注意避免线程死锁、内存泄漏等问题,以确保程序的安全性和稳定性。


















