Skip to content

多线程

概述

多线程是指在同一进程中并发执行多个线程的能力。Java 提供了强大的多线程支持,使得开发者能够编写高效的并发程序。多线程可以提高程序的响应性和资源利用率,适用于需要同时处理多个任务的场景,如网络应用、图形用户界面(GUI)和服务器端应用。

创建线程的方法

在 Java 中,可以通过以下两种主要方式创建线程:

  1. 继承 Thread

    • 创建一个新的类继承自 Thread 类,并重写 run() 方法。
    • 创建线程对象并调用 start() 方法启动线程。

    示例代码

    java
    class MyThread extends Thread {
        @Override
        public void run() {
            System.out.println("线程正在运行: " + Thread.currentThread().getName());
        }
    }
    
    public class ThreadExample {
        public static void main(String[] args) {
            MyThread thread1 = new MyThread();
            thread1.start(); // 启动线程
        }
    }
  2. 实现 Runnable 接口

    • 创建一个类实现 Runnable 接口,并实现 run() 方法。
    • 创建 Thread 对象并将 Runnable 实例作为参数传入,然后调用 start() 方法。

    示例代码

    java
    class MyRunnable implements Runnable {
        @Override
        public void run() {
            System.out.println("线程正在运行: " + Thread.currentThread().getName());
        }
    }
    
    public class RunnableExample {
        public static void main(String[] args) {
            Thread thread1 = new Thread(new MyRunnable());
            thread1.start(); // 启动线程
        }
    }

线程的生命周期

线程的生命周期包括以下几个状态:

  1. 新建(New):线程被创建,但尚未启动。
  2. 就绪(Runnable):线程已启动,等待 CPU 分配时间片。
  3. 运行(Running):线程正在执行。
  4. 阻塞(Blocked):线程因等待某个资源而被阻塞。
  5. 死亡(Dead):线程执行完毕或被终止。

线程同步

在多线程环境中,多个线程可能会同时访问共享资源,导致数据不一致。为了解决这个问题,Java 提供了多种线程同步机制:

  1. 使用 synchronized 关键字

    • 可以在方法或代码块上使用 synchronized 关键字,确保同一时间只有一个线程可以执行该方法或代码块。

    示例代码

    java
    class Counter {
        private int count = 0;
    
        public synchronized void increment() {
            count++;
        }
    
        public int getCount() {
            return count;
        }
    }
    
    public class SynchronizedExample {
        public static void main(String[] args) throws InterruptedException {
            Counter counter = new Counter();
            Thread thread1 = new Thread(() -> {
                for (int i = 0; i < 1000; i++) {
                    counter.increment();
                }
            });
            Thread thread2 = new Thread(() -> {
                for (int i = 0; i < 1000; i++) {
                    counter.increment();
                }
            });
            thread1.start();
            thread2.start();
            thread1.join();
            thread2.join();
            System.out.println("最终计数: " + counter.getCount());
        }
    }
  2. 使用 Lock 接口

    • Java 提供了 java.util.concurrent.locks 包中的 Lock 接口,提供了更灵活的锁机制。

    示例代码

    java
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    class LockCounter {
        private int count = 0;
        private Lock lock = new ReentrantLock();
    
        public void increment() {
            lock.lock();
            try {
                count++;
            } finally {
                lock.unlock();
            }
        }
    
        public int getCount() {
            return count;
        }
    }
    
    public class LockExample {
        public static void main(String[] args) throws InterruptedException {
            LockCounter counter = new LockCounter();
            Thread thread1 = new Thread(() -> {
                for (int i = 0; i < 1000; i++) {
                    counter.increment();
                }
            });
            Thread thread2 = new Thread(() -> {
                for (int i = 0; i < 1000; i++) {
                    counter.increment();
                }
            });
            thread1.start();
            thread2.start();
            thread1.join();
            thread2.join();
            System.out.println("最终计数: " + counter.getCount());
        }
    }

常用的线程类和接口

  • Thread:表示线程的类,提供了创建和控制线程的方法。
  • Runnable:表示可执行的任务的接口,定义了 run() 方法。
  • Callable:类似于 Runnable,但可以返回结果并抛出异常。
  • Future:表示异步计算的结果,可以用于获取 Callable 的返回值。
  • ExecutorService:提供了线程池的功能,简化了线程管理。

个人感悟

多线程编程是 Java 的一大优势,它使得程序能够高效地处理并发任务。理解线程的生命周期、同步机制和常用类是编写高效多线程程序的关键。尽管多线程可以提高程序的性能,但也带来了复杂性,因此在设计多线程程序时需要谨慎考虑线程安全和资源管理。