← 返回首页

Java并发编程详解

📂 java ⏱ 4 min 638 words

什么是并发编程

并发编程允许多个线程同时执行任务,充分利用多核处理器的能力。Java提供了丰富的并发工具来简化多线程编程。

volatile关键字

volatile保证变量的可见性和禁止指令重排序。

public class VolatileDemo {
    private volatile boolean running = true;

    public void run() {
        while (running) {
            System.out.println("运行中...");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                break;
            }
        }
        System.out.println("停止运行");
    }

    public void stop() {
        running = false;
    }

    public static void main(String[] args) throws InterruptedException {
        VolatileDemo demo = new VolatileDemo();
        Thread worker = new Thread(demo::run);
        worker.start();

        Thread.sleep(1000);
        demo.stop();
        worker.join();
    }
}

原子类

原子类提供无锁的线程安全操作。

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

public class AtomicIntegerDemo {
    private static AtomicInteger counter = new AtomicInteger(0);
    private static AtomicReference<String> ref = new AtomicReference<>("初始值");

    public static void main(String[] args) throws InterruptedException {
        Runnable task = () -> {
            for (int i = 0; i < 1000; i++) {
                counter.incrementAndGet();
            }
        };

        Thread[] threads = new Thread[10];
        for (int i = 0; i < 10; i++) {
            threads[i] = new Thread(task);
            threads[i].start();
        }

        for (Thread t : threads) {
            t.join();
        }

        System.out.println("最终计数: " + counter.get());

        System.out.println("比较并设置:");
        boolean success = ref.compareAndSet("初始值", "新值");
        System.out.println("设置结果: " + success + ", 当前值: " + ref.get());
    }
}

Lock接口

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockDemo {
    private final Lock lock = new ReentrantLock();
    private int balance = 1000;

    public void transfer(int amount) {
        lock.lock();
        try {
            if (balance >= amount) {
                balance -= amount;
                System.out.println(Thread.currentThread().getName() +
                    "转出: " + amount + ", 余额: " + balance);
            }
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        LockDemo demo = new LockDemo();

        Runnable task = () -> {
            for (int i = 0; i < 100; i++) {
                demo.transfer(10);
            }
        };

        Thread t1 = new Thread(task, "线程A");
        Thread t2 = new Thread(task, "线程B");

        t1.start();
        t2.start();

        t1.join();
        t2.join();

        System.out.println("最终余额: " + demo.balance);
    }
}

读写锁

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class ReadWriteLockDemo {
    private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
    private int data = 0;

    public int read() {
        rwLock.readLock().lock();
        try {
            System.out.println(Thread.currentThread().getName() +
                "读取数据: " + data);
            return data;
        } finally {
            rwLock.readLock().unlock();
        }
    }

    public void write(int value) {
        rwLock.writeLock().lock();
        try {
            data = value;
            System.out.println(Thread.currentThread().getName() +
                "写入数据: " + data);
        } finally {
            rwLock.writeLock().unlock();
        }
    }
}

CountDownLatch

import java.util.concurrent.CountDownLatch;

public class CountDownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
        int taskCount = 5;
        CountDownLatch latch = new CountDownLatch(taskCount);

        for (int i = 0; i < taskCount; i++) {
            final int taskId = i;
            new Thread(() -> {
                try {
                    Thread.sleep((long) (Math.random() * 1000));
                    System.out.println("任务" + taskId + "完成");
                    latch.countDown();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }

        System.out.println("等待所有任务完成...");
        latch.await();
        System.out.println("所有任务已完成");
    }
}

CyclicBarrier

import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierDemo {
    public static void main(String[] args) {
        int parties = 3;
        CyclicBarrier barrier = new CyclicBarrier(parties, () -> {
            System.out.println("所有线程已到达屏障,继续执行");
        });

        for (int i = 0; i < parties; i++) {
            final int id = i;
            new Thread(() -> {
                try {
                    System.out.println("线程" + id + "正在执行");
                    Thread.sleep((long) (Math.random() * 1000));
                    System.out.println("线程" + id + "到达屏障");
                    barrier.await();
                    System.out.println("线程" + id + "继续执行");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}

Semaphore

import java.util.concurrent.Semaphore;

public class SemaphoreDemo {
    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(3);

        for (int i = 0; i < 10; i++) {
            final int id = i;
            new Thread(() -> {
                try {
                    semaphore.acquire();
                    System.out.println("线程" + id + "获取许可");
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    semaphore.release();
                    System.out.println("线程" + id + "释放许可");
                }
            }).start();
        }
    }
}

CompletableFuture

import java.util.concurrent.CompletableFuture;

public class CompletableFutureDemo {
    public static void main(String[] args) {
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "异步任务结果";
        });

        future.thenAccept(result -> System.out.println("结果: " + result));

        CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> 10);
        CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> 20);

        f1.thenCombine(f2, (a, b) -> a + b)
          .thenAccept(sum -> System.out.println("求和: " + sum));

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

并发编程最佳实践

  1. 优先使用高级并发工具而非低级同步
  2. 使用不可变对象避免线程安全问题
  3. 合理选择锁的粒度
  4. 避免死锁:按固定顺序获取锁
  5. 使用线程池管理线程资源

总结

Java并发编程提供了丰富的工具和机制。理解volatile、原子类、锁和并发工具的使用,能帮助你构建高性能、线程安全的应用程序。