# Java并发编程的基础 ## 引言 在当今多核处理器普及的时代,并发编程已成为提高程序性能的关键手段。Java作为一门成熟的企业级编程语言,提供了丰富的并发编程工具和API。本文将系统介绍Java并发编程的基础知识,包括线程基础、线程安全、同步机制以及常用并发工具类等内容。 ## 一、线程基础 ### 1.1 线程与进程 - **进程**:操作系统资源分配的基本单位,拥有独立的内存空间 - **线程**:CPU调度的基本单位,共享进程内存空间 - **关系**:一个进程包含多个线程,线程是轻量级的进程 ### 1.2 线程创建方式 ```java // 方式1:继承Thread类 class MyThread extends Thread { @Override public void run() { System.out.println("Thread running"); } } // 方式2:实现Runnable接口 class MyRunnable implements Runnable { @Override public void run() { System.out.println("Runnable running"); } } // 方式3:使用Lambda表达式 Thread lambdaThread = new Thread(() -> { System.out.println("Lambda thread running"); });
当多个线程访问共享资源时,可能导致数据不一致的问题,典型场景包括: - 竞态条件(Race Condition) - 内存可见性问题 - 指令重排序问题
// 同步方法 public synchronized void syncMethod() { // 临界区代码 } // 同步代码块 public void syncBlock() { synchronized(this) { // 临界区代码 } } // 静态方法同步 public static synchronized void staticSync() { // 临界区代码 }
保证变量的可见性和禁止指令重排序:
private volatile boolean flag = false;
特性 | synchronized | ReentrantLock |
---|---|---|
实现方式 | JVM内置 | JDK实现 |
可中断 | 不支持 | 支持 |
公平锁 | 非公平 | 可配置 |
条件变量 | 有限支持 | 支持 |
性能 | 优化后较好 | 较高 |
// 初始化计数器 CountDownLatch latch = new CountDownLatch(3); // 工作线程 new Thread(() -> { // 执行任务 latch.countDown(); }).start(); // 主线程等待 latch.await(); System.out.println("所有任务完成");
CyclicBarrier barrier = new CyclicBarrier(3, () -> { System.out.println("所有线程到达屏障"); }); for (int i = 0; i < 3; i++) { new Thread(() -> { try { System.out.println("线程到达"); barrier.await(); } catch (Exception e) { e.printStackTrace(); } }).start(); }
Semaphore semaphore = new Semaphore(3); // 允许3个线程同时访问 new Thread(() -> { try { semaphore.acquire(); // 访问资源 } finally { semaphore.release(); } }).start();
// 创建线程池 ExecutorService executor = Executors.newFixedThreadPool(5); // 提交任务 executor.submit(() -> { System.out.println("Task running"); }); // 关闭线程池 executor.shutdown();
new ThreadPoolExecutor( corePoolSize, // 核心线程数 maximumPoolSize, // 最大线程数 keepAliveTime, // 空闲线程存活时间 unit, // 时间单位 workQueue, // 工作队列 threadFactory, // 线程工厂 handler // 拒绝策略 );
AtomicInteger counter = new AtomicInteger(0); // 原子递增 counter.incrementAndGet(); // CAS操作 boolean success = counter.compareAndSet(expect, update);
高并发场景下性能优于AtomicLong:
LongAdder adder = new LongAdder(); adder.increment(); long sum = adder.sum();
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("key", 1); map.computeIfAbsent("key", k -> 2);
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>(); list.add("item"); list.get(0); // 读取不需要同步
Future<String> future = executor.submit(() -> { Thread.sleep(1000); return "Result"; }); String result = future.get(); // 阻塞获取结果
CompletableFuture.supplyAsync(() -> "Hello") .thenApply(s -> s + " World") .thenAccept(System.out::println);
Java并发编程是一个庞大而复杂的主题,本文仅介绍了基础概念和常用工具。要真正掌握并发编程,需要深入理解Java内存模型(JMM),并在实际项目中不断实践和优化。随着Java版本的更新,并发API也在不断演进(如虚拟线程等),开发者需要持续学习新的技术和最佳实践。
注意:本文示例代码仅用于演示概念,实际使用时需要考虑异常处理、资源释放等细节。 “`
这篇文章大约2200字,涵盖了Java并发编程的主要基础知识点,采用Markdown格式编写,包含代码示例和表格对比,结构清晰。如需进一步扩展某个主题或添加更多实践案例,可以继续补充相关内容。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。