在Java并发编程中,锁策略和原子性操作是非常重要的概念。锁机制确保了多个线程在访问共享资源时不会发生冲突,而CAS(Compare-And-Swap)是一种无锁的并发控制机制,可以在一定程度上解决线程安全问题。本文将围绕常见的锁策略、CAS在Java中的实现,以及Synchronized
的加锁原理进行详细的描述。
一、常见的锁策略
在Java中,锁主要有以下几种策略:
-
悲观锁:假设最坏情况,总是认为会发生冲突,因此在操作共享数据之前先加锁。这是Java中
synchronized
关键字和ReentrantLock
的基本实现。 -
乐观锁:假设不会发生冲突,直接操作共享数据,但在提交时检查是否发生了冲突。如使用CAS实现的原子变量,例如
AtomicInteger
。 -
读写锁:以
ReadWriteLock
形式出现,允许多个线程同时读取共享数据,而写入操作则是独占的。这种策略提高了并发性能。 -
自旋锁:在获取锁时,线程会循环检查锁的状态,适用于锁的持有时间短的场景,以减少上下文切换的开销。
二、CAS在Java中的实现
CAS(Compare and Swap)是一种原子操作,原理是比较内存中某个值与预期值是否相等,如果相等则将其更新为新值。Java提供了许多基于CAS的类,如AtomicInteger
。
下面是一个使用CAS的AtomicInteger
的示例:
import java.util.concurrent.atomic.AtomicInteger;
public class CASExample {
public static void main(String[] args) {
AtomicInteger atomicInt = new AtomicInteger(0);
// 创建多个线程并发修改AtomicInteger的值
for (int i = 0; i < 10; i++) {
new Thread(() -> {
for (int j = 0; j < 1000; j++) {
atomicInt.incrementAndGet(); // CAS 实现的自增
}
}).start();
}
// 等待所有线程执行完毕
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("最终计数值: " + atomicInt.get());
}
}
在上面的代码中,AtomicInteger
的incrementAndGet
方法能够确保多个线程安全地更新整数值,它内部使用了CAS机制。
三、Synchronized的加锁原理
Java中的synchronized
关键字用于实现互斥锁,是最简单的同步方式。它可以用于方法或代码块。使用synchronized
时,JVM会为每个对象或类分配一个监视器锁。
-
对象锁:当
synchronized
用在实例方法上时,锁住的是当前对象的监视器锁;当用在静态方法上时,锁住的是该类的监视器锁。 -
实现原理:当线程访问
synchronized
修饰的方法时,先尝试获得锁,如果获得锁则执行代码块,执行完毕后释放锁;如果未能获得锁,则进入阻塞状态,等待其他线程释放锁。
示例代码如下:
public class SynchronizedExample {
private int count = 0;
// 使用synchronized修饰实例方法
public synchronized void increment() {
count++;
}
public static void main(String[] args) {
SynchronizedExample example = new SynchronizedExample();
// 创建多个线程并发访问increment方法
for (int i = 0; i < 10; i++) {
new Thread(() -> {
for (int j = 0; j < 1000; j++) {
example.increment(); // 线程安全的自增
}
}).start();
}
// 等待所有线程执行完毕
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("最终计数值: " + example.count);
}
}
小结
在高并发环境中,选择合适的锁策略至关重要,CAS提供了无锁的解决方案,而synchronized
是Java提供的基本同步机制。了解这些策略和原理有助于开发高效的并发程序,确保线程安全。