java中的读写锁入门

版权声明:本文为博主原创文章,未经博主允许不得转载。 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();//不管这段代码出现问题,都要释放锁
             }


         }
}
  • 在写的时候,没有任何去打断它
  • 在读的时候,不能有其他线程写
  • 效率高

猜你喜欢

转载自blog.csdn.net/qq_33248299/article/details/78798428
今日推荐