readLock()和writeLock()都是ReadWriteLock接口中定义的方法,用于获取读锁和写锁。
readLock()
方法返回一个读锁,允许多个线程同时获取该锁,以进行并发读取操作。如果当前已有一个写锁或其他线程正在请求写锁,则读锁会被阻塞,直到所有写锁请求完成并释放锁为止。读锁和写锁之间是互斥的。
writeLock()
方法返回一个写锁,只允许一个线程获取该锁,以进行写入操作。如果当前已有一个读锁或其他线程正在请求读锁,则写锁会被阻塞,直到所有读锁请求完成并释放锁为止。写锁是独占的,同一时间只能有一个线程持有写锁。
在使用读写锁时,应该根据具体的业务场景和需求选择适当的锁类型。如果共享资源的读取操作远远超过写入操作,那么使用读写锁可以提高系统的并发性能。如果写入操作非常频繁,那么使用读写锁可能会导致读取操作的性能下降,因为读取线程需要等待写入线程释放写锁。此外,读写锁也需要消耗额外的系统资源,因此应该避免不必要的锁竞争。
我们先看下面这段代码
本来应该是1写入,然后1写入完全
但是现在1写入后,紧跟着的是3写入
这明显是错误的
下面我们来加上锁,解决问题
package org.Test6;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ReadWriteLockDemo {
public static void main(String[] args) {
MyCacheLock myCache = new MyCacheLock();
//写入
for(int i=1;i<=5;i++){
final int temp=i;
new Thread(()->{
myCache.put(temp+"",temp+"");
},String.valueOf(i)).start();
}
//读取
for(int i=1;i<=5;i++){
final int temp=i;
new Thread(()->{
myCache.get(temp+"");
},String.valueOf(i)).start();
}
}
}
//自定义缓存
class MyCacheLock{
private volatile Map<String,Object> map = new HashMap<>();
private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
//存 写 写入的时候
// 只希望只有一个线程去写
public void put(String key,Object value){
readWriteLock.writeLock().lock(); //加锁
try {
System.out.println(Thread.currentThread().getName()+"写入"+key);
map.put("key","value");
System.out.println(Thread.currentThread().getName()+"写入结束");
} catch (Exception e) {
e.printStackTrace();
}finally {
readWriteLock.writeLock().unlock(); //解锁
}
}
//取 读
//读的时候,所有人都可以读
public void get(String key){
readWriteLock.readLock().lock(); //加锁
try {
System.out.println(Thread.currentThread().getName()+"读取"+key);
Object o=map.get("key");
System.out.println(Thread.currentThread().getName()+"读取结束");
} catch (Exception e) {
e.printStackTrace();
}finally {
readWriteLock.readLock().unlock(); //解锁
}
}
}
这段代码中,读操作和写操作的主要区别在于使用的锁不同,
读操作
使用ReadWriteLock
实例中的readLock()获取读锁,而写操作
使用writeLock()
获取写锁。
读写锁允许多个线程同时读取共享资源,但只允许一个线程写入共享资源。因此,在读操作中,多个线程可以同时获得读锁并读取共享资源,而写操作需要获取排他的写锁,以防止其他线程同时写入共享资源。
在MyCacheLock中,put()方法使用writeLock()获取写锁,以确保只有一个线程在写入数据时修改共享资源,而get()方法使用readLock()获取读锁,允许多个线程同时读取数据。
这种读写锁的机制可以提高并发性能,因为允许多个线程同时读取共享资源,而不会产生数据冲突,同时通过只允许一个线程写入共享资源,可以避免写操作的数据竞争和不一致性。
独占锁(写锁):一次只能被一个线程占有
共享锁(读锁):多个线程可以同时占有
在技术的道路上,我们不断探索、不断前行,不断面对挑战、不断突破自我。科技的发展改变着世界,而我们作为技术人员,也在这个过程中书写着自己的篇章。让我们携手并进,共同努力,开创美好的未来!愿我们在科技的征途上不断奋进,创造出更加美好、更加智能的明天!