美文网首页
ReentrantReadWriteLock用法

ReentrantReadWriteLock用法

作者: sunpy | 来源:发表于2018-11-06 21:22 被阅读7次

    介绍

    ReentrantLock是互斥排他锁,同一时间只能有一个线程在执行任务,ReentrantLock支持锁的重入功能,虽然保证了线程的安全性,但是效率不高,实际上应该是写操作互斥,读操作共享。而jdk提供了读写锁ReentrantReadWriteLock。

    读读共享

    public class MyTask {
    
        private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
        
        public void read() {
            try {
                lock.readLock().lock();
                System.out.println(Thread.currentThread().getName() + " start");
                Thread.sleep(10000);
                System.out.println(Thread.currentThread().getName() + " end");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.readLock().unlock();
            }
        }
    }
    
    public class ReadReadTest {
    
        public static void main(String[] args) {
            final MyTask myTask = new MyTask();
            
            Thread t1 = new Thread(new Runnable() {
    
                @Override
                public void run() {
                    myTask.read();
                }
            });
            t1.setName("t1");
            
            Thread t2 = new Thread(new Runnable() {
    
                @Override
                public void run() {
                    myTask.read();
                }
            });
            t2.setName("t2");
            
            t1.start();
            t2.start();
        }
    }
    

    结果:

    t2 start
    t1 start
    t1 end
    t2 end
    

    写写互斥

    public class MyTask {
    
        private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
        
        public void write() {
            try {
                lock.writeLock().lock();
                System.out.println(Thread.currentThread().getName() + " start");
                Thread.sleep(10000);
                System.out.println(Thread.currentThread().getName() + " end");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.writeLock().unlock();
            }
        }
    }
    
    public class ReadReadTest {
    
        public static void main(String[] args) {
            final MyTask myTask = new MyTask();
            
            Thread t1 = new Thread(new Runnable() {
    
                @Override
                public void run() {
                    myTask.write();
                }
            });
            t1.setName("t1");
            
            Thread t2 = new Thread(new Runnable() {
    
                @Override
                public void run() {
                    myTask.write();
                }
            });
            t2.setName("t2");
            
            t1.start();
            t2.start();
        }
    }
    

    结果:

    t1 start
    t1 end
    t2 start
    t2 end
    

    读写互斥

    public class MyTask {
    
        private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
        
        public void read() {
            try {
                lock.readLock().lock();
                System.out.println(Thread.currentThread().getName() + " start");
                Thread.sleep(10000);
                System.out.println(Thread.currentThread().getName() + " end");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.readLock().unlock();
            }
        }
        
        public void write() {
            try {
                lock.writeLock().lock();
                System.out.println(Thread.currentThread().getName() + " start");
                Thread.sleep(10000);
                System.out.println(Thread.currentThread().getName() + " end");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.writeLock().unlock();
            }
        }
    }
    
    public class ReadReadTest {
    
        public static void main(String[] args) {
            final MyTask myTask = new MyTask();
            
            Thread t1 = new Thread(new Runnable() {
    
                @Override
                public void run() {
                    myTask.read();
                }
            });
            t1.setName("t1");
            
            Thread t2 = new Thread(new Runnable() {
    
                @Override
                public void run() {
                    myTask.write();
                }
            });
            t2.setName("t2");
            
            t1.start();
            
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            
            t2.start();
        }
    }
    

    结果:

    t1 start
    t1 end
    t2 start
    t2 end
    

    写读互斥

    public class ReadReadTest {
    
        public static void main(String[] args) {
            final MyTask myTask = new MyTask();
            
            Thread t1 = new Thread(new Runnable() {
    
                @Override
                public void run() {
                    myTask.write();
                }
            });
            t1.setName("t1");
            
            Thread t2 = new Thread(new Runnable() {
    
                @Override
                public void run() {
                    myTask.read();
                }
            });
            t2.setName("t2");
            
            t1.start();
            
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            
            t2.start();
        }
    }
    

    结果:

    t1 start
    t1 end
    t2 start
    t2 end
    

    总结

    读操作的锁叫共享锁,写操作的锁叫排他锁。就是遇见写锁就需互斥。那么以此可得出读读共享,写写互斥,读写互斥,写读互斥。

    相关文章

      网友评论

          本文标题:ReentrantReadWriteLock用法

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