美文网首页
主要并发工具类-ReadWriteLock的使用

主要并发工具类-ReadWriteLock的使用

作者: 飞奔吧牛牛 | 来源:发表于2020-02-10 05:22 被阅读0次

    使用场景:
    程序中有如下三种互斥情况:读/读,写/写,读/写。在大多数情况下我们只需要控制读/写,写/写两种情况互斥即可,读/读操作不用做同步。当程序中读/读操作的比例较大时,如果还使用ReentrantLock,则其同步机制会照成大量的排队。可是使用ReadWriteLock可以极大的提高程序的性能。

    ReentrantLock和ReadWriteLock使用起来基本一致。下面测试下两者在频繁进行读操作时的性能。
    开三个线程分别进行循环10次的写操作,开1000个线程进行读操作。
    ReentrantLock 性能测试:

    public class P2_ReadWriteLock {
        String name;
        ReentrantLock lock = new ReentrantLock();
    //    ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    
        public void setName(String name) {
            lock.lock();
    //        lock.writeLock().lock();
            try {
                this.name = name;
                System.out.println(Thread.currentThread().getName() + " setName " + this.name);
                //假设该类型操作消耗一点时间
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
    //            lock.writeLock().unlock();
            }
        }
    
        public void printName() {
            lock.lock();
    //        lock.readLock().lock();
            try {
                System.out.println(Thread.currentThread().getName() + " name is " + name);
                //假设该类型操作需要消耗一点时间
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
    //            lock.readLock().unlock();
            }
        }
    
        public static void main(String[] args) {
            P2_ReadWriteLock client = new P2_ReadWriteLock();
            long startTime = System.currentTimeMillis();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 10; i++) {
                        client.setName(Thread.currentThread().getName());
                    }
                }
            }).start();
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 10; i++) {
                        client.setName(Thread.currentThread().getName());
                    }
                }
            }).start();
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 10; i++) {
                        client.setName(Thread.currentThread().getName());
                    }
                }
            }).start();
            new Date().getTime();
            for (int i = 0; i < 1000; i++) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        client.printName();
                        System.out.println(Thread.currentThread().getName() + " 耗时:" + (System.currentTimeMillis() - startTime));
                    }
                }).start();
            }
    
    
        }
    }
    
    

    结果:

    Thread-999 耗时:11028
    Thread-1000 name is Thread-2
    Thread-1000 耗时:11039
    Thread-1001 name is Thread-2
    Thread-1001 耗时:11050
    Thread-1002 name is Thread-2
    Thread-1002 耗时:11061
    

    ReadWriteLock:

    public class P2_ReadWriteLock {
        String name;
    //    ReentrantLock lock = new ReentrantLock();
        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    
        public void setName(String name) {
    //        lock.lock();
            lock.writeLock().lock();
            try {
                this.name = name;
                System.out.println(Thread.currentThread().getName() + " setName " + this.name);
                //假设该类型操作消耗一点时间
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
    //            lock.unlock();
                lock.writeLock().unlock();
            }
        }
    
        public void printName() {
    //        lock.lock();
            lock.readLock().lock();
            try {
                System.out.println(Thread.currentThread().getName() + " name is " + name);
                //假设该类型操作需要消耗一点时间
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
    //            lock.unlock();
                lock.readLock().unlock();
            }
        }
    
        public static void main(String[] args) {
            P2_ReadWriteLock client = new P2_ReadWriteLock();
            long startTime = System.currentTimeMillis();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 10; i++) {
                        client.setName(Thread.currentThread().getName());
                    }
                }
            }).start();
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 10; i++) {
                        client.setName(Thread.currentThread().getName());
                    }
                }
            }).start();
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 10; i++) {
                        client.setName(Thread.currentThread().getName());
                    }
                }
            }).start();
            new Date().getTime();
            for (int i = 0; i < 1000; i++) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        client.printName();
                        System.out.println(Thread.currentThread().getName() + " 耗时:" + (System.currentTimeMillis() - startTime));
                    }
                }).start();
            }
    
    
        }
    }
    
    

    结果:

    Thread-561 耗时:448
    Thread-552 耗时:448
    Thread-559 耗时:448
    Thread-551 耗时:448
    Thread-549 耗时:448
    

    总结:
    当满足读/写互斥,写/写互斥,而读/读不需要互斥,且读/读操作的比例比较大时,换成读写锁更好。

    相关文章

      网友评论

          本文标题:主要并发工具类-ReadWriteLock的使用

          本文链接:https://www.haomeiwen.com/subject/parethtx.html