Java并发与多线程:完整指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Java中的并发与多线程:从理论到实践



在现代软件世界中,应用程序的性能直接取决于有效利用处理器资源的能力。Java中的并发与多线程是关键概念,它们允许同时执行多个任务、加速数据处理并创建响应迅速的用户界面。在本文中,我们将分析Java中多线程的基本机制,学习如何创建和管理线程,并探讨避免常见错误的最佳实践。



什么是线程以及如何在Java中创建它?



线程(thread)是一个轻量级进程,在单个应用程序内执行。每个线程都有自己的调用栈,并且可以独立于其他线程工作。在Java中,有两种主要的创建线程的方法。



方法1:继承Thread类

public class MyThread extends Thread {    @Override    public void run() {        System.out.println("线程 " + getName() + " 已启动!");    }

public static void main(String[] args) { MyThread thread = new MyThread(); thread.start(); // 启动线程 }}


方法2:实现Runnable接口

public class MyRunnable implements Runnable {    @Override    public void run() {        System.out.println("线程通过Runnable执行");    }

public static void main(String[] args) { Thread thread = new Thread(new MyRunnable()); thread.start(); }}


推荐使用第二种方法,因为它不需要继承,并且允许同时实现多个接口。



线程同步:避免竞争条件



当多个线程同时访问共享数据时,会出现竞争条件(race condition)。为了避免这种情况,Java提供了同步机制。



synchronized关键字

阻塞其他线程对方法或代码块的访问,直到当前线程执行完毕:

public class Counter {    private int count = 0;

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

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


使用Lock进行锁定

一种比synchronized更灵活的机制。允许设置超时并尝试获取锁而不阻塞:

import java.util.concurrent.locks.ReentrantLock;

public class SafeCounter { private final ReentrantLock lock = new ReentrantLock(); private int count = 0;

public void increment() { lock.lock(); try { count++; } finally { lock.unlock(); // 始终释放锁 } }}


线程池与ExecutorService



为每个任务创建新线程是一项昂贵的操作。为了有效管理线程,请使用java.util.concurrent包中的ExecutorService。



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

public class ThreadPoolExample { public static void main(String[] args) { // 创建一个包含4个线程的线程池 ExecutorService executor = Executors.newFixedThreadPool(4);

for (int i = 0; i < 10; i++) { final int taskId = i; executor.submit(() -> { System.out.println("任务 " + taskId + " 正在 " + Thread.currentThread().getName() + " 中执行"); }); }

executor.shutdown(); // 在所有任务执行完毕后关闭线程池 }}


主要的线程池类型:

  • newFixedThreadPool(n) — 固定数量的线程

博客

书籍推荐