Java多线程之显示锁和内置锁总结详解
前言
随着现代计算机的发展,CPU的速度和核心数量逐渐增加,让多线程编程变得越来越重要。Java作为一门支持多线程的语言,在多线程编程方面也提供了一系列的API和机制。本文将重点介绍Java中的两种锁:显示锁和内置锁,并对它们进行详细分析和对比。
什么是锁?
在多线程编程中,为了保证共享资源的正确访问,我们经常需要对这些共享资源进行加锁操作,这时就需要使用锁机制。锁机制主要用于三个目的:
- 互斥:同一时刻只允许一个线程访问锁保护的资源;
- 可见性:一个线程修改了锁保护的共享变量,其他线程可以看到这个修改;
- 有序性:锁的获取和释放具有一定的顺序性,以保证程序正确性。
显示锁
显示锁是Java提供的一种手动管理锁的机制,最主要的类是 java.util.concurrent.locks.Lock
。Lock接口定义了两个基本方法,分别是 lock()
和 unlock()
。在代码块中使用Lock锁进行同步时,需要手动获取锁和释放锁,代码示例:
Lock lock = new ReentrantLock();
...
lock.lock();
try {
// 执行需要同步的操作
} catch (Exception e) {
// 异常处理
} finally {
lock.unlock();
}
显示锁相比于内置锁更加灵活,它支持条件变量,可以响应中断请求,同时也支持读写锁,可以控制读写操作的并发访问等。
内置锁
内置锁是Java的默认锁机制,也称为 synchronized 同步块,它是Java中最简单和最常见的同步机制之一。内置锁的锁对象是调用该同步块的对象,同一时刻只有一个线程能够获取锁,其他线程需要等待该锁的释放才能继续执行。示例代码:
synchronized (obj) {
// 执行需要同步的操作
}
内置锁的优点是使用方便,不需要手动获取和释放锁,自动管理。缺点是功能相对简单,只能支持最基本的互斥性。
总结
- 显示锁是Java提供的一种手动管理锁的机制,Lock接口定义了两个基本方法;
- 内置锁是Java默认的锁机制,也称为synchronized同步块;
- 显示锁比内置锁更加灵活,支持条件变量,可以响应中断请求,同时也支持读写锁;
- 内置锁使用方便,不需要手动获取和释放锁,自动管理。但功能相对简单,只能支持最基本的互斥性。
示例
示例一:使用显示锁实现多线程同步
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class SyncTest {
private int count = 0;
private Lock lock = new ReentrantLock();
public void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
public void decrement() {
lock.lock();
try {
count--;
} finally {
lock.unlock();
}
}
public static void main(String[] args) throws InterruptedException {
SyncTest syncTest = new SyncTest();
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
syncTest.increment();
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
syncTest.decrement();
}
});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println(syncTest.count);
}
}
该示例使用显示锁来保证 count 总是在多线程环境下正确,Lock.lock()方法获取锁,try...finally 语句中的 unlock() 方法释放锁。运行该程序会产生 0 的输出,证明了程序的正确性。
示例二:使用内置锁实现多线程同步
public class SyncTest {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized void decrement() {
count--;
}
public static void main(String[] args) throws InterruptedException {
SyncTest syncTest = new SyncTest();
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
syncTest.increment();
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
syncTest.decrement();
}
});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println(syncTest.count);
}
}
该示例使用内置锁来保证 count 总是在多线程环境下正确,使用 synchronized 对方法进行同步。运行该程序会产生 0 的输出,证明了程序的正确性。
结语
本文对Java中的显示锁和内置锁进行了详细的介绍和比较,并给出了代码示例。在多线程编程中,锁机制是保证程序正确性的重要手段,使用锁机制时需要根据实际情况进行选择。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java多线程之显示锁和内置锁总结详解 - Python技术站