第四周总结
Java 学习第四周总结
一、学习概述
本周聚焦于 Java 并发编程与函数式编程的深入学习,系统掌握了线程创建与同步机制、并发工具类的应用、函数式接口与 Lambda 表达式,以及 CompletableFuture 异步编程和 volatile 关键字的底层原理。通过理论学习与实践案例结合,深入理解了 Java 内存模型(JMM)的工作机制,为构建高性能、高并发的 Java 应用奠定了基础。
二、并发编程核心技术
(一)线程创建与同步
- 线程创建方式
- 继承 Thread 类:通过子类重写 run () 方法实现线程逻辑,但存在单继承限制。
class MyThread extends Thread {
@Override
public void run() {
System.out.println("线程执行");
}
}
new MyThread().start();
2. 实现 Runnable 接口:推荐方式,避免单继承限制,支持函数式编程。
class Task implements Runnable {
@Override
public void run() { /* 任务逻辑 */ }
}
new Thread(new Task()).start();
2. 线程同步机制
3. synchronized 关键字:可修饰方法或代码块,确保临界区线程安全。
public synchronized void increment() { count++; } // 同步方法
synchronized (lockObj) { // 同步代码块
// 临界区操作
}
4. Lock 接口:提供更灵活的锁控制,支持尝试获取锁、可中断锁等。
Lock lock = new ReentrantLock();
lock.lock();
try {
// 操作共享资源
} finally {
lock.unlock(); // 确保锁释放
}
3. 线程池应用
通过 ExecutorService 管理线程生命周期,避免频繁创建线程的性能开销。
ExecutorService pool = Executors.newFixedThreadPool(3); // 固定大小线程池
pool.submit(() -> System.out.println("异步任务执行"));
pool.shutdown(); // 优雅关闭线程池
(二)线程通信与并发工具类
- 线程通信机制
- wait()/notify():基于监视器锁的条件等待机制,需在同步代码块中使用。
class Buffer {
private Queue
private int capacity = 2;
public synchronized void produce(int item) throws InterruptedException {
while (queue.size() == capacity) wait(); // 缓冲区满时等待
queue.add(item);
notifyAll(); // 唤醒所有等待线程
}
public synchronized int consume() throws InterruptedException {
while (queue.isEmpty()) wait(); // 缓冲区空时等待
int item = queue.poll();
notifyAll();
return item;
}
}
2. 并发工具类
6. CountDownLatch:一次性屏障,等待指定数量线程完成后继续。
CountDownLatch latch = new CountDownLatch(3);
ExecutorService pool = Executors.newFixedThreadPool(3);
for (int i = 0; i < 3; i++) {
pool.submit(() -> {
// 任务执行
latch.countDown();
});
}
latch.await(); // 阻塞等待所有任务完成
7. CyclicBarrier:可循环使用的屏障,多线程到达屏障点后一起继续。
CyclicBarrier barrier = new CyclicBarrier(3, () -> {
System.out.println("所有线程到达屏障");
});
for (int i = 0; i < 3; i++) {
new Thread(() -> {
try {
// 任务执行
barrier.await(); // 等待其他线程
} catch (Exception e) {}
}).start();
}
8. ConcurrentHashMap:线程安全的哈希表,采用分段锁优化并发性能。
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
map.put("key", 100);
map.computeIfAbsent("name", k -> k.length()); // 原子操作
三、函数式编程与异步编程
(一)函数式接口与 Lambda 表达式
- 函数式接口定义
仅含一个抽象方法的接口,可添加@FunctionalInterface注解校验。
@FunctionalInterface
interface Calculator {
int calculate(int a, int b); // 唯一抽象方法
default void log() { /* 默认方法 */ }
}
// Lambda表达式实现
Calculator add = (a, b) -> a + b;
2. 方法引用
通过方法名直接引用已存在的方法,简化 Lambda 表达式。
List
names.forEach(System.out::println); // 实例方法引用
names.sort(String::compareToIgnoreCase); // 类方法引用
3. Lambda 底层原理
通过invokedynamic指令动态生成字节码,本质是匿名内部类的语法糖。
Runnable r = () -> System.out.println("Run");
// 等价于
Runnable r = new Runnable() {
@Override
public void run() {
System.out.println("Run");
}
};
(二)CompletableFuture 异步编程
- 核心特性
- 链式调用:支持thenApply、thenAccept等方法串联异步任务。
- 异常处理:通过exceptionally处理异步任务异常。
- 任务组合:allOf等待所有任务完成,anyOf任一任务完成即返回。
- 基础使用
// 无返回值异步任务
CompletableFuture
System.out.println("任务1执行");
});
// 有返回值异步任务
CompletableFuture
return "Result";
});
// 链式处理
task2.thenApply(s -> s + "_processed")
.thenAccept(System.out::println) // 输出 "Result_processed"
.exceptionally(ex -> {
System.out.println("错误处理");
return null;
});
// 任务组合
CompletableFuture
allTasks.join(); // 等待所有任务完成
四、内存模型与可见性控制
(一)volatile 关键字
- 核心作用
- 可见性:确保线程读取变量时从主内存获取最新值。
- 禁止指令重排序:防止编译器和 CPU 优化导致代码执行顺序异常。
- 使用场景
适用于状态标记变量,但不保证原子性(如flag = !flag需额外同步)。
class SharedResource {
private volatile boolean flag = false; // 保证多线程可见性
public void toggleFlag() {
flag = !flag; // 非原子操作,volatile不保证原子性
}
}
(二)Java 内存模型(JMM)
- 内存结构
- 主内存:所有线程共享的公共内存区域。
- 工作内存:线程私有的变量副本,操作变量需先拷贝到工作内存。
- happens-before 原则
- volatile 写操作先于后续对该变量的读操作。
- 线程启动、终止、中断等操作具有顺序性约束。
五、本周学习总结与反思
(一)学习成果 - 掌握线程创建的两种方式及同步机制,能熟练使用 synchronized 与 Lock 接口。
- 熟练应用 CountDownLatch、CyclicBarrier 等并发工具类解决线程协作问题。
- 理解函数式接口本质,能灵活使用 Lambda 表达式与方法引用简化代码。
- 掌握 CompletableFuture 异步编程模型,实现非阻塞式任务处理。
- 深入理解 volatile 关键字的可见性原理与 JMM 的工作机制。
(二)存在问题 - 对复杂并发场景下的锁优化(如读写锁、分段锁)理解不足。
- CompletableFuture 的高级组合操作(如 thenCombine、applyToEither)应用不够熟练。
- volatile 与 synchronized 的适用场景区分不够清晰,可能导致误用。
(三)改进方向 - 深入学习 JUC 包中的高级锁机制(ReadWriteLock、StampedLock)。
- 通过实战案例练习 CompletableFuture 的复杂任务组合场景。
- 研读 JMM 规范,理解 happens-before 原则的具体应用场景。
(四)下周计划 - 学习 Java IO 与 NIO 编程模型,对比 BIO/NIO/AIO 的差异。
- 探索网络编程基础,实现简单的 Socket 通信案例。
- 学习数据库连接池技术(如 HikariCP)与 JDBC 编程。
- 开展并发编程综合项目,整合本周所学知识。
浙公网安备 33010602011771号