版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_33248299/article/details/78798428
读写锁:分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,写锁与写锁互斥,这是由jvm自己控制的,你只要上好相应的锁即可。如果你的低吗只读数据,可以很多人同时读,但不能同时写,那就上读锁;如果你的代码修改数据,只能有一个人再写,且不能同时读取,那就上写锁。总之,读的时候上读锁,写的时候上写锁!
我们先写一个程序,一共十个线程,五个线程读数据,五个线程取数据
- 不加任何互斥代码如下
public class ReadWriterLockTest {
public static void main(String[] args) {
final Queue queue = new Queue();
for(int i = 1 ;i<=5;i++){
new Thread(new Runnable() {
@Override
public void run() {
while(true) {
queue.get();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while(true) {
queue.put(new Random().nextInt(10000));
}
}
}).start();
}
}
}
class Queue{
private Object data = null;
public void get(){
try {
System.out.println(Thread.currentThread().getName()+ " be ready to read data!");
Thread.sleep((long)(Math.random()*1000));
System.out.println(Thread.currentThread().getName()+ " have read data : " + data);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void put(Object data){
try {
System.out.println(Thread.currentThread().getName()+" be ready to write data!");
Thread.sleep((long)(Math.random()*1000));
this.data=data;
System.out.println(Thread.currentThread().getName()+" have write data : " +data);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
因为你并没有加互斥,所以此时代码运行在读得过程中会产生写的效果,如下
那么此时怎么办?或许有人会想用Lock来解决?真的可以嘛?
答案是否定的,上了Lock,就是不管是读还是写都进不去了,你们可以去试试
用Lock,不论是写还是读通通都是互斥了
此时我们就用要Java提供的另一种锁,读写锁ReadWriteLock(Lock的子类)
public class ReadWriterLockTest {
public static void main(String[] args) {
final Queue queue = new Queue();
for(int i = 1 ;i<=5;i++){
new Thread(new Runnable() {
@Override
public void run() {
while(true) {
queue.get();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while(true) {
queue.put(new Random().nextInt(10000));
}
}
}).start();
}
}
}
class Queue{
private Object data = null;
ReadWriteLock rwl = new ReentrantReadWriteLock();
public void get(){
rwl.readLock().lock();
try {
System.out.println(Thread.currentThread().getName()+ " be ready to read data!");
Thread.sleep((long)(Math.random()*1000));
System.out.println(Thread.currentThread().getName()+ " have read data : " + data);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
rwl.readLock().unlock();//不管这段代码出现问题,都要释放锁
}
}
public void put(Object data){
rwl.writeLock().lock();
try {
System.out.println(Thread.currentThread().getName()+" be ready to write data!");
Thread.sleep((long)(Math.random()*1000));
this.data=data;
System.out.println(Thread.currentThread().getName()+" have write data : " +data);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
rwl.writeLock().unlock();//不管这段代码出现问题,都要释放锁
}
}
}
- 在写的时候,没有任何去打断它
- 在读的时候,不能有其他线程写
- 效率高