JDK并发包--重入锁

Posted halazi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDK并发包--重入锁相关的知识,希望对你有一定的参考价值。

重入锁基本使用:
    使用java.util.concurrent.locks.ReentrantLock 类来实现,可以替代synchronized关键字。如下例,重入锁有着显示的操作过程,开发者可以手动指定在哪里加锁,在哪里释放(退出临界区时必须释放,不然其他线程没有机会再访问了)。重入的意思是,同一个线程可以多次获得锁,同样的退出时需要多次释放。
    public class LockDemo implements Runnable{
        public static ReentrantLock lock = new ReentrantLock();
        public static int i=0;
        public finnal int N= 10000;
        @Override
        public void run(){
            for(int j=0;j<N;j++){
                lock.lock();    //加锁
                lock.lock();
                try(
                    i++;
                )finally{
                    lock.unlock();    //释放锁
                    lock.unlock();
                }
            }
        }
        public static void main(String[] args){
            LockDemo tLock = new LockDemo();
            Thread t1 = new Thread(tLock);
            Thread t2 = new Thread(tLock);
            t1.start();t2.start();
            t1.join();t2.join();
            System.out.println(i);//最终输出20000
        }
    }

中断响应:
    对锁的请求使用lockInterruptibly()方法,可以在等待锁的过程中响应中断
    package com.test;
    import java.util.concurrent.locks.ReentrantLock;

    public class IntruptLock implements Runnable{
        public static ReentrantLock lock1 = new ReentrantLock();
        public static ReentrantLock lock2 = new ReentrantLock();
        int lock;//控制加锁顺序,方便构成死锁
        public IntruptLock(int lock){this.lock = lock;}
        public void run(){
            try{
                if(lock==1){
                    while(true){
                        lock1.lockInterruptibly();
                        try{
                            Thread.sleep(1000);
                        }catch(InterruptedException e) {
                        
                        }
                        lock2.lockInterruptibly();    
                    }
                }else {
                    while(true){
                        lock2.lockInterruptibly();
                        try {
                            Thread.sleep(1000);
                        }catch(InterruptedException e) {
                            lock1.lockInterruptibly();
                        }
                    }
                }
            }catch(InterruptedException e){
                e.printStackTrace();
            }finally{
                if(lock1.isHeldByCurrentThread()) {
                    lock1.unlock();
                }
                if(lock2.isHeldByCurrentThread()) {
                    lock2.unlock();
                }
                System.out.println(Thread.currentThread().getName()+":线程退出");
            }
        }
        public static void main(String[] args) throws InterruptedException {
            IntruptLock r1 = new IntruptLock(1);
            IntruptLock r2 = new IntruptLock(2);
            //t1先获得lock1锁,再申请lock2,t2先获得lock2锁,再申请lock1,构成死锁
            Thread t1 = new Thread(r1);
            Thread t2 = new Thread(r2);
            t1.start();
            t2.start();
            Thread.sleep(1000);
            t2.interrupt();//中断t2,lock2响应中断,t2释放lock2锁,t1得以执行下去
        }
    }

tryLock():
    仍然是上个栗子,如果使用的是tryLock(),t2在申请lock1时没有获得,它不会傻傻的等,而是会立刻返回false,然后继续执行重新尝试,只要时间够长,总会获得lock1而执行下去。
    tryLock()也可以传入参数,tryLock(10,TimeUnit.SECONDS),分别表示时长和时间单位。

公平锁:
    public ReentrantLock(boolean fair),各线程获得公平锁的概率是相等的。




























































































以上是关于JDK并发包--重入锁的主要内容,如果未能解决你的问题,请参考以下文章

重入锁

JDK并发包

Java并发包4--可重入锁ReentrantLock的实现原理

JDK并发包[同步控制]

Java并发-- ReentrantLock 可重入锁实现原理1 - 获取锁

J.U.C重入锁