zoukankan      html  css  js  c++  java
  • hadoop08---读写锁

    ReentrantLock
    直接使用lock接口的话,我们需要实现很多方法,不太方便,ReentrantLock是唯一实现了Lock接口的类,并且ReentrantLock提供了更多的方法,ReentrantLock,意思是“可重入锁”。
    
    以下是ReentrantLock的使用案例:
    
      例子1,lock()的正确使用方法
        见代码MyLockTest
    
    例子2,tryLock()的使用方法
    见代码MyTryLock
    
    例子3,lockInterruptibly()响应中断的使用方法: 
    见代码MyInterruptibly
    ReadWriteLock
      ReadWriteLock也是一个接口,在它里面只定义了两个方法:
    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();
    }
     一个用来获取读锁,一个用来获取写锁。也就是说将文件的读写操作分开,分成2个锁来分配给线程,从而使得多个线程可以同时进行读操作。下面的ReentrantReadWriteLock实现了ReadWriteLock接口。
    
    ReentrantReadWriteLock
      ReentrantReadWriteLock里面提供了很多丰富的方法,不过最主要的有两个方法:readLock()和writeLock()用来获取读锁和写锁。
    
    下面通过几个例子来看一下ReentrantReadWriteLock具体用法。
    例子1:假如有多个线程要同时进行读操作的话,先看一下synchronized达到的效果
    见代码MySynchronizedReadWrite 
    
    例子2:改成用读写锁的话:
    见代码MyReentrantReadWriteLock
    注意:
      不过要注意的是,如果有一个线程已经占用了读锁,则此时其他线程如果要申请写锁,则申请写锁的线程会一直等待释放读锁。
    如果有一个线程已经占用了写锁,则此时其他线程如果申请写锁或者读锁,则申请的线程会一直等待释放写锁。
      
    Lock和synchronized的选择
      
      1)Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现;
      2)synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而Lock在发生异常时,如果没有主动通过unLock()去释放锁,则很可能造成死锁现象,因此使用Lock时需要在finally块中释放锁;
      3)Lock可以让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不能够响应中断;
      4)通过Lock可以知道有没有成功获取锁,而synchronized却无法办到。
      5)Lock可以提高多个线程进行读操作的效率。
      在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时(即有大量线程同时竞争),此时Lock的性能要远远优于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) {//get方法被锁住synchronized,不管是读还是写同一时刻只能一个线程进来
            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()+"读写操作完毕");
        }
    
    }
    package cn.itcast_01_mythread.thread.lock;
    
    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();
                }
            }
    }
    
    
    //0在读的时候1可以读。0在写的时候别人不可以写。
    
    /*Thread-0写操作完毕
    Thread-1正在进行写操作
    Thread-1正在进行写操作
    Thread-1正在进行写操作
    Thread-1正在进行写操作
    Thread-1正在进行写操作
    Thread-1正在进行写操作
    Thread-1正在进行写操作
    Thread-1正在进行写操作
    Thread-1正在进行写操作
    Thread-1正在进行写操作
    Thread-1正在进行写操作
    Thread-1正在进行写操作
    Thread-1正在进行写操作
    Thread-1正在进行写操作
    Thread-1正在进行写操作*/
  • 相关阅读:
    mysql BETWEEN操作符 语法
    mysql IN操作符 语法
    mysql LIKE通配符 语法
    mysql TOP语句 语法
    mysql DELETE语句 语法
    mysql Update语句 语法
    mysql INSERT语句 语法
    mysql ORDER BY语句 语法
    mysql OR运算符 语法
    mysql AND运算符 语法
  • 原文地址:https://www.cnblogs.com/yaowen/p/9015763.html
Copyright © 2011-2022 走看看