Java 多线程编程:使用 ReentrantLock 实现同步访问
Java 多线程编程:使用 ReentrantLock 实现同步访问
本教程将演示如何使用 Java 中的 ReentrantLock 实现多线程同步访问,以防止数据竞争。代码示例展示了如何使用 Lock 接口和 try-finally 块来确保线程安全。
问题描述
在多线程环境中,多个线程可能会同时访问共享资源,导致数据竞争和不可预期的结果。为了避免这种情况,我们需要使用同步机制来控制线程对共享资源的访问。
使用 ReentrantLock 实现同步
ReentrantLock 是 Java 中提供的可重入锁,它允许同一个线程多次获取同一把锁。使用 ReentrantLock 可以确保同一时间只有一个线程可以访问共享资源。
示例代码:
package step3;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Task {
public static void main(String[] args) {
final Insert insert = new Insert();
Thread t1 = new Thread(new Runnable() {
public void run() {
insert.insert(Thread.currentThread());
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
insert.insert(Thread.currentThread());
}
});
Thread t3 = new Thread(new Runnable() {
public void run() {
insert.insert(Thread.currentThread());
}
});
// 设置线程优先级
t1.setPriority(Thread.MAX_PRIORITY);
t2.setPriority(Thread.NORM_PRIORITY);
t3.setPriority(Thread.MIN_PRIORITY);
t1.start();
t2.start();
t3.start();
}
}
class Insert {
public static int num;
// 在这里定义Lock
private Lock lock = new ReentrantLock();
public void insert(Thread thread) {
/********* Begin *********/
lock.lock();
try {
System.out.println(thread.getName() + '得到了锁');
for (int i = 0; i < 5; i++) {
num++;
System.out.println(num);
}
} finally {
System.out.println(thread.getName() + '释放了锁');
lock.unlock();
}
/********* End *********/
}
}
代码解释:
- 在
Insert类中,我们定义了一个ReentrantLock对象lock。 - 在
insert方法中,我们使用lock.lock()获取锁,并使用try-finally块来确保锁最终会被释放。 - 在
try块中,我们执行需要同步的代码块,即对num变量的增量操作和打印语句。 - 在
finally块中,我们使用lock.unlock()释放锁,无论try块中是否发生异常。
总结
使用 ReentrantLock 可以有效地实现多线程同步访问,确保数据的一致性。在编写多线程程序时,一定要注意同步机制的使用,以避免数据竞争和不可预期的结果。
注意:
ReentrantLock是一种可重入锁,这意味着同一个线程可以多次获取同一把锁,而不会造成死锁。- 使用
try-finally块来确保锁最终会被释放,无论try块中是否发生异常。 ReentrantLock是一种显式锁,需要手动获取和释放。
原文地址: https://www.cveoy.top/t/topic/nVba 著作权归作者所有。请勿转载和采集!