Java多线程之锁学习(增强版)攻略
什么是锁?
锁是一种同步机制,用于协调对共享资源的访问。在Java中,可以使用synchronized
关键字或Lock
接口来实现锁。
synchronized锁
synchronized
关键字可以修饰方法和代码块。当多个线程访问被synchronized
修饰的方法或代码块时,只有一个线程可以执行,其他线程需要等待。
修饰方法
public synchronized void method() {
//方法体
}
修饰代码块
public void method() {
synchronized (lock) {
//这里是需要同步的代码块
}
}
Lock锁
Java提供了Lock
接口来实现锁。Lock
相比synchronized
更加灵活,具备更多的功能,如可重入性、可中断性、公平性等。
ReentrantLock
ReentrantLock
是Lock
接口的实现类,具备可重入性,可以用于替代synchronized
。
Lock lock = new ReentrantLock();
public void method() {
lock.lock();
try {
//这里是需要同步的代码块
} finally {
lock.unlock();
}
}
Condition
Condition
是Lock
接口中的一个重要概念,可以用于线程间的协调。每个Condition
实例都与一个Lock
实例绑定。
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
//线程1
lock.lock();
try {
while (!conditionMet) {
condition.await();
}
} finally {
lock.unlock();
}
//线程2
lock.lock();
try {
//改变条件
conditionMet = true;
condition.signal(); //唤醒等待线程
} finally {
lock.unlock();
}
锁的注意事项
- 锁的范围尽量控制到最小范围,避免使用过多锁导致死锁等问题。
- 尽量使用
Lock
接口,避免使用synchronized
关键字,在某些情况下性能可能更好。 - 可以使用
ThreadLocal
来实现线程间数据的隔离。
示例说明
示例一
以下是使用synchronized
关键字实现线程安全的单例模式的代码:
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
当一个线程执行到getInstance()
方法时,其他线程需要等待。
示例二
以下是使用ReentrantLock
实现线程安全的单例模式的代码:
public class Singleton {
private static Singleton instance;
private static Lock lock = new ReentrantLock();
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
lock.lock();
try {
if (instance == null) { //双重检查
instance = new Singleton();
}
} finally {
lock.unlock();
}
}
return instance;
}
}
使用ReentrantLock
实现线程安全的单例模式可以提高性能,避免每次调用getInstance()
时都需要等待。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java多线程之锁学习(增强版) - Python技术站