您好,登录后才能下订单哦!
在Java中,锁(Lock)是一种用于控制多个线程对共享资源访问的机制。通过使用锁,可以确保在同一时间只有一个线程能够访问共享资源,从而避免数据竞争和不一致性问题。Java提供了多种锁机制,包括内置的synchronized
关键字和java.util.concurrent.locks
包中的显式锁。
synchronized
关键字synchronized
是Java中最基本的锁机制,它可以用于方法或代码块,确保同一时间只有一个线程能够执行被锁定的代码。
通过在方法声明中添加synchronized
关键字,可以将整个方法锁定。当一个线程进入该方法时,其他线程必须等待该线程退出方法后才能进入。
public class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
synchronized
也可以用于代码块,锁定特定的对象。这种方式比同步方法更灵活,因为它允许你只锁定需要同步的部分代码。
public class Counter {
private int count = 0;
private final Object lock = new Object();
public void increment() {
synchronized (lock) {
count++;
}
}
public int getCount() {
synchronized (lock) {
return count;
}
}
}
ReentrantLock
ReentrantLock
是java.util.concurrent.locks
包中的一个显式锁实现。与synchronized
相比,ReentrantLock
提供了更多的功能,如可中断的锁获取、超时锁获取、公平锁等。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Counter {
private int count = 0;
private final Lock lock = new ReentrantLock();
public void increment() {
lock.lock(); // 获取锁
try {
count++;
} finally {
lock.unlock(); // 释放锁
}
}
public int getCount() {
lock.lock();
try {
return count;
} finally {
lock.unlock();
}
}
}
ReentrantLock
允许线程在等待锁的过程中被中断,这在某些情况下非常有用。
public void incrementInterruptibly() throws InterruptedException {
lock.lockInterruptibly(); // 可中断的锁获取
try {
count++;
} finally {
lock.unlock();
}
}
ReentrantLock
还支持超时锁获取,即线程在指定的时间内尝试获取锁,如果超时则放弃。
public boolean incrementWithTimeout(long timeout, TimeUnit unit) throws InterruptedException {
if (lock.tryLock(timeout, unit)) { // 尝试获取锁,超时则返回false
try {
count++;
return true;
} finally {
lock.unlock();
}
}
return false;
}
ReentrantLock
可以配置为公平锁,即按照线程请求锁的顺序来分配锁。默认情况下,ReentrantLock
是非公平的。
private final Lock fairLock = new ReentrantLock(true); // 公平锁
ReadWriteLock
ReadWriteLock
是一种特殊的锁,它允许多个读线程同时访问共享资源,但在写线程访问时,所有读线程和其他写线程都会被阻塞。ReentrantReadWriteLock
是ReadWriteLock
的一个实现。
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class SharedResource {
private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
private int data = 0;
public void readData() {
rwLock.readLock().lock();
try {
System.out.println("Read data: " + data);
} finally {
rwLock.readLock().unlock();
}
}
public void writeData(int newData) {
rwLock.writeLock().lock();
try {
data = newData;
System.out.println("Write data: " + data);
} finally {
rwLock.writeLock().unlock();
}
}
}
StampedLock
StampedLock
是Java 8引入的一种新的锁机制,它提供了更细粒度的锁控制,并且在某些场景下性能优于ReadWriteLock
。
import java.util.concurrent.locks.StampedLock;
public class SharedResource {
private final StampedLock stampedLock = new StampedLock();
private int data = 0;
public void readData() {
long stamp = stampedLock.tryOptimisticRead();
int currentData = data;
if (!stampedLock.validate(stamp)) {
stamp = stampedLock.readLock();
try {
currentData = data;
} finally {
stampedLock.unlockRead(stamp);
}
}
System.out.println("Read data: " + currentData);
}
public void writeData(int newData) {
long stamp = stampedLock.writeLock();
try {
data = newData;
System.out.println("Write data: " + data);
} finally {
stampedLock.unlockWrite(stamp);
}
}
}
Java提供了多种锁机制来满足不同的并发需求。synchronized
是最简单的锁机制,适用于大多数场景。ReentrantLock
提供了更多的功能和灵活性,适用于需要更复杂控制的场景。ReadWriteLock
和StampedLock
则适用于读多写少的场景,能够提高并发性能。
在选择锁机制时,应根据具体的应用场景和需求来决定使用哪种锁。合理使用锁可以有效地避免并发问题,提高程序的性能和稳定性。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。