(39)读写锁ReadWriteLock

ReadWriteLock也是一个接口,在它里面只定义了两个方法:

一个用来获取读锁,一个用来获取写锁。也就是说将文件的读写操作分开,分成2个锁来分配给线程,从而使得多个线程可以同时进行读操作

public interface ReadWriteLock {

    /**

     * Returns the lock used for reading.

     * @return the lock used for reading.

     */

    Lock readLock();  // 获取读锁

    /**

     * Returns the lock used for writing.

     * @return the lock used for writing.

     */

    Lock writeLock();  //获取写锁

}

一旦有线程获得了写锁,其他线程就不能再做操作;若有线程获得了读锁,其他线程仍可以进行读操作。

下面的ReentrantReadWriteLock实现了ReadWriteLock接口。

ReentrantReadWriteLock里面提供了很多丰富的方法,不过最主要的有两个方法:readLock()writeLock()用来获取读锁和写锁。

下面通过几个例子来看一下ReentrantReadWriteLock的具体用法。

例子1:假如有多个线程要同时进行读操作的话,先看一下synchronized达到的效果

package cn.itcast_01_mythread.thread.lock;

/**
* 一个线程又要读又要写,用synchronize来实现的话,读写操作都只能锁住后一个线程一个线程地进行
* @author
*
*/
public class MySynchronizedReadWrite {
       public static void main(String[] args) {
              final MySynchronizedReadWrite test = new MySynchronizedReadWrite();
              new Thread(){
                      public void run() {
                             test.get(Thread.currentThread());
                      };
               }.start();
              new Thread(){
                      public void run() {
                             test.get(Thread.currentThread());
                      };
               }.start();

       }

       public synchronized void get(Thread thread) {
              long start = System.currentTimeMillis();
              int i=0;
              while(System.currentTimeMillis() - start <= 1) {
                     i++;
                     if(i%4==0){
                            System.out.println(thread.getName()+"正在进行写操作");
                     }else {
                            System.out.println(thread.getName()+"正在进行读操作");
                      }
              }
            System.out.println(thread.getName()+"读写操作完毕");
       }

}

例子2:改成用读写锁的话

import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
* 使用读写锁,可以实现读写分离锁定,读操作并发进行,写操作锁定单个线程
*
* 如果有一个线程已经占用了读锁,则此时其他线程如果要申请写锁,则申请写锁的线程会一直等待释放读锁。
* 如果有一个线程已经占用了写锁,则此时其他线程如果申请写锁或者读锁,则申请的线程会一直等待释放写锁。
* @author
*
*/
public class MyReentrantReadWriteLock {
        private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

        public static void main(String[] args) {
               final MyReentrantReadWriteLock test = new MyReentrantReadWriteLock();
               new Thread(){
                       public void run() {
                               test.get(Thread.currentThread());
                               test.write(Thread.currentThread());
                       };
                }.start();

              new Thread(){
                      public void run() {
                             test.get(Thread.currentThread());
                             test.write(Thread.currentThread());
                      };
               }.start();

         }

       /**
         * 读操作,用读锁来锁定
         * @param thread
        */
        public void get(Thread thread) {
               rwl.readLock().lock();  //获取读锁
               try {
                    long start = System.currentTimeMillis();
                    while(System.currentTimeMillis() - start <= 1) {
                          System.out.println(thread.getName()+"正在进行读操作");
                     }
                    System.out.println(thread.getName()+"读操作完毕");
                     } finally {
                     rwl.readLock().unlock();
                }
         }

        /**
          * 写操作,用写锁来锁定
          * @param thread
         */
         public void write(Thread thread) {
                rwl.writeLock().lock();  //获取写锁
                try {
                       long start = System.currentTimeMillis();
                       while(System.currentTimeMillis() - start <= 1) {
                             System.out.println(thread.getName()+"正在进行写操作");
                        }
                       System.out.println(thread.getName()+"写操作完毕");
                   } finally {
                       rwl.writeLock().unlock();
                    }
         }
}

猜你喜欢

转载自www.cnblogs.com/paradis/p/11431967.html