zoukankan      html  css  js  c++  java
  • ReentrantLock说明

    ReentrantLock与synchronized一样都可以用来控制多线线程对共享资源的访问。
    synchronized关键字是隐式的获得锁,即进入synchronized方法或者synchronized代码会自动的获得锁,离开同步方法或者同步代码块自动释放锁。
    ReentrantLock相对于synchronized来说对锁的操作更加灵活,ReentrantLock可以显示的获得锁 和 释放锁。
    对ReentrantLock锁的释放要写在finally代码块下,保证ReentrantLock获得锁后,一定会被释放。
    不要将ReentrantLock获得锁的代码写在try代码块下,因为如果ReentrantLock获得锁时方式异常,异常抛出的同时会导致锁无故释放,然后在finally代码块中再释放ReentrantLock锁的话,会报错。
    ReentrantLock提供的synchronized关键字不具备的主要特性:
    • 尝试非阻塞的获得锁,当前线程获得锁时,如果锁已经被其他线程获得,可以立即返回false。
    • 能被中断的获得锁,即当线程获得锁后,当前线程被中断后,当前线程可以继续运行。
    • 超时获得锁,在指定时间内获得锁,如果在指定时间内获得锁则返回true,如果在指定时间内获得不到锁,则返回false。
    针对上面的三个特定以及ReentrantLock具体的获得锁方法,编写测试代码如下:
    测试主方法:
    public class MainTest {
        public static void main(String[] args) throws InterruptedException {
            ReentrantLock lock = new ReentrantLock();
            Thread threadA = new Thread(new ThreadA(lock));
            threadA.setName("线程A");
            Thread threadB = new Thread(new ThreadB(lock));
            threadB.setName("线程B");
            threadB.start();
            Thread.sleep(1000);
            threadA.start();
        }
    //测试线程B
    public class ThreadB implements Runnable{
        private ReentrantLock lock;
        public ThreadB(ReentrantLock lock) {
            this.lock = lock;
        }
        public void run() {
            lock.lock();
            try {
                System.out.println("B对象获得锁");
                Thread.sleep(5000);
            }catch (Exception ex) {
                ex.printStackTrace();
            }finally {
                lock.unlock();
            }
        }
    }
    }
    void lock(),lock方式是阻塞方式的获得锁,B线程获得锁后等待了5秒,在这个过程中A线程尝试获得锁,在B线程等待期间线程A一直处于阻塞状态,直到线程B释放锁后A线程才获得锁。
    public class ThreadA  implements Runnable{
        private ReentrantLock lock;
        public ThreadA(ReentrantLock lock) {
            this.lock = lock;
        }
        public void run(){
                lock.lock();
                try {
                    System.out.println("A对象获得锁");
                }catch (Exception ex) {
                    ex.printStackTrace();
                }finally {
                    lock.unlock();
                }
        }
    }
    指定结果:
    B对象获得锁
    B对象等待5秒
    A对象获得锁
    boolean tryLock(),tryLock方式为立即获得锁,如果获得不到则返回false,B线程获得锁后等待了5秒,在这个等待过程中A线程尝试获得锁,结果锁一直被B线程拿着,所以A线程直接返回false,修改测试类A:
    public class ThreadA  implements Runnable{
        private ReentrantLock lock;
        public ThreadA(ReentrantLock lock) {
            this.lock = lock;
        }
        public void run(){
                if (lock.tryLock()){
                    try {
                        System.out.println("A对象获得锁");
                    }catch (Exception ex) {
                        ex.printStackTrace();
                    }finally {
                        lock.unlock();
                    }
                }
        }
    }
    指定结果:
    B对象获得锁
    B对象等待5秒
    void lockInterruptibly(),lockInterruptibly获得锁后,如果当前线程获得锁后,代码中进行了interrupt中断后,线程可以继续进行,不会抛出移除,修改测试类A,增加中断代码:
    //测试线程A
    public class ThreadA  implements Runnable{
        private ReentrantLock lock;
    
        public ThreadA(ReentrantLock lock) {
            this.lock = lock;
        }
    
        public void run(){
            try {
                lock.lockInterruptibly();
                try {
                    System.out.println("A对象开始中断");
                    Thread.currentThread().interrupt();
                    System.out.println("A对象结束中断");
                }catch (Exception ex) {
                    ex.printStackTrace();
                }finally {
                    System.out.println("A对象释放锁");
                    lock.unlock();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    指定结果:
    B对象获得锁
    A对象开始中断
    A对象结束中断
    A对象释放锁
    boolean tryLock(long timeout, TimeUnit unit),tryLock方式为在一段时间内获得锁,如果获得不到则返回false,B线程获得锁后等待了5秒,在这个等待过程中A线程如果在一秒内获得锁,获得锁,则返回true,否则返回false:
    public class ThreadA  implements Runnable{
        private ReentrantLock lock;
        public ThreadA(ReentrantLock lock) {
            this.lock = lock;
        }
        public void run(){
            try {
                if (lock.tryLock(6, TimeUnit.SECONDS)){
                    try {
                        System.out.println("A对象在6秒内获得锁");
                    }catch (Exception ex) {
                        ex.printStackTrace();
                    }finally {
                        lock.unlock();
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    指定结果:
    B对象获得锁
    B对象等待5秒
    A对象在6秒内获得锁
    收藏文章数量从多到少与“把书读薄”是一个道理
  • 相关阅读:
    使用FolderBrowserDialog组件选择文件夹
    使用OpenFileDialog组件打开多个文
    使用OpenFileDialog组件打开对话框
    获取弹出对话框的相关返回值
    PAT 甲级 1139 First Contact (30 分)
    PAT 甲级 1139 First Contact (30 分)
    PAT 甲级 1138 Postorder Traversal (25 分)
    PAT 甲级 1138 Postorder Traversal (25 分)
    PAT 甲级 1137 Final Grading (25 分)
    PAT 甲级 1137 Final Grading (25 分)
  • 原文地址:https://www.cnblogs.com/use-D/p/9740725.html
Copyright © 2011-2022 走看看