zoukankan      html  css  js  c++  java
  • 并发编程-concurrent指南-Lock-可重入锁(ReentrantLock)

    可重入和不可重入的概念是这样的:当一个线程获得了当前实例的锁,并进入方法A,这个线程在没有释放这把锁的时候,能否再次进入方法A呢?

    • 可重入锁:可以再次进入方法A,就是说在释放锁前此线程可以再次进入方法A(方法A递归)。
    • 不可重入锁(自旋锁):不可以再次进入方法A,也就是说获得锁进入方法A是此线程在释放锁钱唯一的一次进入方法A。

    ,具体区别查看可重入锁和不可重入锁区别

    ReentrantLock,意思是“可重入锁”。ReentrantLock是唯一实现了Lock接口的类,并且ReentrantLock提供了更多的方法。下面通过一些实例看具体看一下如何使用ReentrantLock。

    lock()的正确使用方法

    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class MainLock {
        private Lock lock = new ReentrantLock();
        public static void main(String[] args) {
            final MainLock mainLock = new MainLock();
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    mainLock.insert(Thread.currentThread());
                }
            }).start();
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    mainLock.insert(Thread.currentThread());
                }
            }).start();
        }
    
        public void insert(Thread thread){
            lock.lock();//获取锁
            try{
                System.out.println(thread.getName() + "获取锁");
                for(int i=0;i<5;i++){
                    System.out.println("------------------------" + thread.getName() + ":"+i+"------------------------");
                }
            }finally {
                System.out.println(thread.getName() + "释放锁");
                lock.unlock();//释放锁
            }
        }
    }

    结果:

    Thread-0获取锁
    ------------------------Thread-0:0------------------------
    ------------------------Thread-0:1------------------------
    ------------------------Thread-0:2------------------------
    ------------------------Thread-0:3------------------------
    ------------------------Thread-0:4------------------------
    Thread-0释放锁
    Thread-1获取锁
    ------------------------Thread-1:0------------------------
    ------------------------Thread-1:1------------------------
    ------------------------Thread-1:2------------------------
    ------------------------Thread-1:3------------------------
    ------------------------Thread-1:4------------------------
    Thread-1释放锁

    tryLock()的使用方法

    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class MainTryLock {
        private Lock lock = new ReentrantLock();
        public static void main(String[] args) {
            final MainTryLock mainTryLock = new MainTryLock();
    
            new Thread(){
                @Override
                public void run() {
                    mainTryLock.insert(Thread.currentThread());
                }
            }.start();
    
            new Thread(){
                @Override
                public void run() {
                    mainTryLock.insert(Thread.currentThread());
                }
            }.start();
        }
    
        public void insert(Thread thread){
            if(lock.tryLock()){
                try{
                    System.out.println(thread.getName() + "获取锁");
                    for(int i=0;i<5;i++){
                        Thread.sleep(200);
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    System.out.println(thread.getName() + "释放锁");
                    lock.unlock();//释放锁
                }
            }else{
                System.out.println(thread.getName()+"未获取到锁");
            }
        }
    }

    结果:

    Thread-0获取锁
    Thread-1未获取到锁
    Thread-0释放锁

    lockInterruptibly()响应中断的使用方法:

    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class MainLockInterruptibl {
        private  Lock lock = new ReentrantLock();
        public static void main(String[] args)  {
            MainLockInterruptibl test = new MainLockInterruptibl();
            MyThread thread1 = new MyThread(test);
            MyThread thread2 = new MyThread(test);
            thread1.start();
            thread2.start();
    
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            thread2.interrupt();
        }
    
        public void insert(Thread thread) throws InterruptedException{
            lock.lockInterruptibly();   //注意,如果需要正确中断等待锁的线程,必须将获取锁放在外面,然后将InterruptedException抛出
            try {
                System.out.println(thread.getName()+"得到了锁");
                long startTime = System.currentTimeMillis();
                for( int i=0;i<5;i++) {
                    TimeUnit.SECONDS.sleep(2);
                }
            } catch (Exception e){
                e.printStackTrace();
            }finally {
                System.out.println(Thread.currentThread().getName()+"执行finally");
                lock.unlock();
                System.out.println(thread.getName()+"释放了锁");
            }
        }
        static class MyThread extends Thread {
            private MainLockInterruptibl test = null;
            public MyThread(MainLockInterruptibl test) {
                this.test = test;
            }
            @Override
            public void run() {
                try {
                    test.insert(Thread.currentThread());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    System.out.println(Thread.currentThread().getName()+"被中断");
                }
            }
        }
    }

    结果:

    Thread-0得到了锁
    java.lang.InterruptedException
    Thread-1被中断
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireInterruptibly(AbstractQueuedSynchronizer.java:898)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1222)
        at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335)
        at com.concurrent.MainLockInterruptibl.insert(MainLockInterruptibl.java:25)
        at com.concurrent.MainLockInterruptibl$MyThread.run(MainLockInterruptibl.java:48)
    Thread-0执行finally
    Thread-0释放了锁

    源码地址:https://github.com/qjm201000/concurrent_reentrantLock.git

  • 相关阅读:
    Changing Icon File Of Push Button At Runtime In Oracle Forms 6i
    Set Font Properties On Mouse Hover Of Push Button And Text Items At Run time In Oracle Forms
    Change An Item Property Using Set_Item_Property In Oracle Forms
    Calling / Running a report in Oracle forms 10g / 11g
    Change Or Set Report Object Property At Run Time In Oracle Forms Using Set_Report_Object_Property Command
    Refresh / Updating a form screen in Oracle D2k Forms 6i
    Know How And When To Use System.Message_Level To Control Messages In Oracle Forms
    Perform Cut Copy Paste Operations Using Cut_Region Copy_Region Paste_Region Commands In Oracle Forms
    CHECKBOX_CHECKED built-in in Oracle D2k Forms
    Limiting To Select Only 5 Check Boxes Out Of Ten In Oracle Forms
  • 原文地址:https://www.cnblogs.com/qjm201000/p/10175489.html
Copyright © 2011-2022 走看看