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正在进行写操作*/
  • 相关阅读:
    MMSkeleton 快速开始,使用 WebCam 测试
    【数据结构】用详细图文把「栈」搞明白(原理篇)
    详解|写完这篇文章我终于搞懂链表了
    如何掌握 C 语言的一大利器——指针?
    图示加代码 搞懂线性表(一)
    Kafka工作原理与工作过程
    Zookeeper的安装及集群搭建
    Linux中JDK安装
    Nginx性能调优
    Nginx配置--静态代理&反向代理&负载均衡&动静分离&虚拟主机
  • 原文地址:https://www.cnblogs.com/yaowen/p/9015763.html
Copyright © 2011-2022 走看看