补充知识点
一、Lambda表达式
1.1 Lambda表达式
1、定义:Lambda 表达式是 Java 8 引入的一种函数式编程特性,可以用来实现匿名函数或函数式接口。
2、Lambda 表达式的语法:
- 参数列表: 参数列表用小括号 () 括起来,可以指定零个或多个参数。如果没有/只有一个参数,小括号可以省略。如(a, b), x ->, () ->
- 箭头符号:分割参数列表 -> Lambda 表达式的主体部分。
- Lambda 表达式的主体:
- 表达式:可以省略 return 关键字。如x -> x * x
- 代码块。一条语句可以省略{};多条语句需要用大括号 {} 括起来,并且明确指定 return 关键字。如(x, y) -> { int sum = x + y; return sum; }
1.2 方法引用介绍(只有一行方法体时)
1、定义:是 Java 8 中引入的一种语法特性,可以直接引用已有的方法或构造函数。方法引用可以替代 Lambda 表达式。
2、方法引用的形式:
静态方法引用:类名::静态方法名
实例方法引用:实例对象::实例方法名
对象方法引用:语法为 类名::实例方法名
构造函数引用:类名::new
// 使用 Lambda 表达式实现一个接口的方法
interface Greeting {
void sayHello();
}
public class LambdaExample {
public static void main(String[] args) {
//原始匿名内部类方式
Greeting greeting = new Greeting() {
@Override
public void sayHello(int a) {
System.out.println("Hello, world!");
}
};
a->System.out.println("Hello, world!")
// 使用 Lambda 表达式实现接口的方法
greeting = () -> System.out.println("Hello, world!");
// 使用引用方法:() -> 类.XXX(); -> 类::方法名
System.out::println;
greeting.sayHello();// 调用接口的方法
}
}
二、乐观锁&悲观锁
乐观锁和悲观锁是在并发编程中用于处理并发访问和资源竞争的两种不同的锁机制,是两种解决并发数据问题的思路,不是具体技术。
1、悲观锁
- 基本思想:“先保护,再修改”。在整个数据访问过程中,将共享资源锁定,以确保其他线程或进程不能同时访问和修改该资源。
- 应用描述:线程在访问共享资源之前会获取到锁,并在整个操作过程中保持锁的状态,阻塞其他线程的访问。只有当前线程完成操作后,才会释放锁,让其他线程继续操作资源。这种锁机制可以确保资源独占性和数据的一致性,但是在高并发环境下,悲观锁的效率相对较低。
- 实现方案和技术:
- 锁机制:使用传统的锁机制,如互斥锁(Mutex Lock)或读写锁(Read-Write Lock)来保证对共享资源的独占访问。
- 数据库锁:在数据库层面使用行级锁或表级锁来控制并发访问。
- 信号量(Semaphore):使用信号量来限制对资源的并发访问。
2、乐观锁
- 基本思想:“先修改,后校验”。认为并发冲突的概率较低,因此不需要提前加锁,而是在数据更新阶段进行冲突检测和处理。
- 应用描述:线程在读取共享资源时不会加锁,而是记录特定的版本信息。当线程准备更新资源时,会先检查该资源的版本信息是否与之前读取的版本信息一致,如果一致则执行更新操作,否则说明有其他线程修改了该资源,需要进行相应的冲突处理。乐观锁通过避免加锁操作,提高了系统的并发性能和吞吐量,但是在并发冲突较为频繁的情况下,乐观锁会导致较多的冲突处理和重试操作。
- 实现方案和技术:
- 版本号/时间戳:为数据添加一个版本号或时间戳字段,每次更新数据时,比较当前版本号或时间戳与期望值是否一致,若一致则更新成功,否则表示数据已被修改,需要进行冲突处理。
- CAS(Compare-and-Swap):使用原子操作比较当前值与旧值是否一致,若一致则进行更新操作,否则重新尝试。
- 无锁数据结构:采用无锁数据结构,如无锁队列、无锁哈希表等,通过使用原子操作实现并发安全。