Skip to content

多线程和并发

多线程和并发编程是现代编程中非常重要的概念,特别是在需要提高程序性能、处理大量任务或保持程序响应性的情况下。

线程的五个基本状态

  • 可运行
  • 运行
  • 等待锁
  • 等待队列(已释放锁,等待被唤醒,唤醒后进入“等待锁”状态)
  • 其他等待状态(释放处理器,不释放锁,结束之后进入可运行态)

创建线程的方式

  • thread
  • runnable
  • callable
  • 线程池

一、多线程

多线程是指一个程序中包含多个线程,每个线程可以独立执行不同的任务。在 Java 中,可以通过继承 Thread 类或实现 Runnable 接口来创建线程。例如:

java
class MyThread extends Thread {
    public void run() {
        // 线程要执行的任务
    }
}

public class Main {
    public static void main(String[] args) {
        MyThread thread1 = new MyThread();
        MyThread thread2 = new MyThread();
        thread1.start();
        thread2.start();
    }
}

或者使用 Runnable 接口:

java
class MyRunnable implements Runnable {
    public void run() {
        // 线程要执行的任务
    }
}

public class Main {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        Thread thread1 = new Thread(myRunnable);
        Thread thread2 = new Thread(myRunnable);
        thread1.start();
        thread2.start();
    }
}

线程生命周期

线程在其生命周期中可以处于以下几种状态:

  • 新建 (NEW):线程被创建,但尚未启动。
  • 运行 (RUNNABLE):线程正在运行,或者准备好运行。
  • 阻塞 (BLOCKED):线程被阻塞,等待监视器锁定。
  • 等待 (WAITING):线程等待另一个线程执行特定操作。
  • 计时等待 (TIMED_WAITING):线程在指定时间内等待另一个线程执行特定操作。
  • 终止 (TERMINATED):线程已经完成执行。

二、并发

并发是指在同一时间段内,系统可以同时执行多个任务。在 Java 中,可以通过 synchronized 关键字和 Lock 接口来实现对共享资源的访问控制,避免多个线程同时访问共享资源造成的数据竞争和不一致性问题。

java
// 示例:使用同步方法
class Counter {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }

    public synchronized int getCount() {
        return count;
    }
}

除了使用 synchronized 关键字外,还可以使用 Lock 接口来实现锁定:

java
// 示例:使用 ReentrantLock(锁)
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class Counter {
    private int count = 0;
    private Lock lock = new ReentrantLock();

    public void increment() {
        lock.lock();
        try {
            count++;
        } finally {
            lock.unlock();
        }
    }

    public int getCount() {
        lock.lock();
        try {
            return count;
        } finally {
            lock.unlock();
        }
    }
}

三、线程池

核心参数

  • corePoolSize
  • maxnumPoolSize
  • workQueue
  • keepAliveTime
  • unit
  • threadFactory
  • handler

线程池是管理多个线程的机制,避免频繁地创建和销毁线程,从而提高性能和资源利用率。Java 提供了 ExecutorService 接口和 Executors 工具类来管理线程池。

示例:使用线程池

java
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadPoolExample {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(10);

        for (int i = 0; i < 100; i++) {
            executor.execute(() -> {
                System.out.println("Task executed by " + Thread.currentThread().getName());
            });
        }

        executor.shutdown();
    }
}

并发工具类

Java 提供了许多并发工具类来帮助开发者更容易地实现复杂的并发控制。

ExecutorService

ExecutorService 是一个用于管理线程池的接口,提供了异步执行任务的方法。

示例:使用 ExecutorService

java
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExecutorServiceExample {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(5);

        for (int i = 0; i < 10; i++) {
            executor.submit(() -> {
                System.out.println("Task executed by " + Thread.currentThread().getName());
            });
        }

        executor.shutdown();
    }
}

CountDownLatch

CountDownLatch 是一个同步辅助类,允许一个或多个线程等待其他线程完成一组操作。

示例:使用 CountDownLatch

java
import java.util.concurrent.CountDownLatch;

public class CountDownLatchExample {
    public static void main(String[] args) throws InterruptedException {
        int threadCount = 3;
        CountDownLatch latch = new CountDownLatch(threadCount);

        for (int i = 0; i < threadCount; i++) {
            new Thread(() -> {
                System.out.println("Thread " + Thread.currentThread().getName() + " is running");
                latch.countDown();
            }).start();
        }

        latch.await();  // 主线程等待所有工作线程完成
        System.out.println("All threads have finished");
    }
}

CyclicBarrier

CyclicBarrier 是一个同步辅助类,允许一组线程相互等待,直到所有线程都达到某个公共屏障点。

示例:使用 CyclicBarrier

java
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierExample {
    public static void main(String[] args) {
        int threadCount = 3;
        CyclicBarrier barrier = new CyclicBarrier(threadCount, () -> {
            System.out.println("All threads have reached the barrier");
        });

        for (int i = 0; i < threadCount; i++) {
            new Thread(() -> {
                System.out.println("Thread " + Thread.currentThread().getName() + " is running");
                try {
                    barrier.await();  // 等待其他线程到达屏障
                } catch (InterruptedException | BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}