什么叫可重入锁

原文链接:什么叫可重入锁 – 编程屋

可重入性:就是一个线程不用释放,可以重复的获取一个锁n次,只是在释放的时候,也需要相应的释放n次。(简单来说:A线程在某上下文中或得了某锁,当A线程想要在次获取该锁时,不会应为锁已经被自己占用,而需要先等到锁的释放)假使A线程即获得了锁,又在等待锁的释放,就会造成死锁。

注意:synchronizedreentrantlock都是可重入锁

synchronized:

无需释放锁,synchronized会自动释放锁

    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (this) {
                    System.out.println("第1次获取锁,这个锁是:" + this);
                    int index = 1;
                    while (true) {
                        synchronized (this) {
                            System.out.println("第" + (++index) + "次获取锁,这个锁是:" + this);
                        }
                        if (index == 10) {
                            break;
                        }
                    }
                }
            }
        }).start();
    }

reentrantlock:

上几次锁,就需要手动释放几次。

  public static void main(String[] args) {

        ReentrantLock reentrantLock = new ReentrantLock();
        new Thread(() -> {
            try {
                reentrantLock.lock();
                System.out.println("第1次获取这个锁,这个锁是:"+reentrantLock);

                int index = 1;
                while (true) {
                    try {
                        reentrantLock.lock();
                        System.out.println("第"+(++index)+"次获取这个锁,这个锁是:"+reentrantLock);

                        if (index == 10 ) {
                            break;
                        }
                    } finally {
                        reentrantLock.unlock();
                    }
                }
            } finally {
                reentrantLock.unlock();
            }
        }).start();

    }

测试结果:

什么叫可重入锁_第1张图片

注意:如果此时少释放一次锁会出现什么情况:

正常情况(加锁和释放锁次数相同):

 public static void main(String[] args) {

        ReentrantLock reentrantLock = new ReentrantLock();
        new Thread(() -> {
            try {
                reentrantLock.lock();
                System.out.println("第1次获取这个锁,这个锁是:"+reentrantLock);

                int index = 1;
                while (true) {
                    try {
                        reentrantLock.lock();
                        System.out.println("第"+(++index)+"次获取这个锁,这个锁是:"+reentrantLock);

                        if (index == 10 ) {
                            break;
                        }
                    } finally {
                        reentrantLock.unlock();
                    }
                }
            } finally {
                reentrantLock.unlock();
            }
        }).start();


        /**
         * 构建第二个线程 看是否可以获取锁
         */
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    reentrantLock.lock();
                    for (int i = 0; i < 5; i++) {
                        System.out.println("threadName:" + Thread.currentThread().getName());
                        try {
                            Thread.sleep(new Random().nextInt(200));
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                } finally {
                    reentrantLock.unlock();
                }
            }
        }).start();


    }

正常测试结果:

什么叫可重入锁_第2张图片

 异常情况(少释放一次锁):

 public static void main(String[] args) {

        ReentrantLock reentrantLock = new ReentrantLock();
        new Thread(() -> {
            try {
                reentrantLock.lock();
                System.out.println("第1次获取这个锁,这个锁是:"+reentrantLock);

                int index = 1;
                while (true) {
                    try {
                        reentrantLock.lock();
                        System.out.println("第"+(++index)+"次获取这个锁,这个锁是:"+reentrantLock);

                        if (index == 10 ) {
                            break;
                        }
                    } finally {
//                        reentrantLock.unlock();  //锁少释放一次
                    }
                }
            } finally {
                reentrantLock.unlock();
            }
        }).start();


        /**
         * 构建第二个线程 看是否可以获取锁
         */
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    reentrantLock.lock();
                    for (int i = 0; i < 5; i++) {
                        System.out.println("threadName:" + Thread.currentThread().getName());
                        try {
                            Thread.sleep(new Random().nextInt(200));
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                } finally {
                    reentrantLock.unlock();
                }
            }
        }).start();


    }

异常结果(第二个线程一直没有获取到锁):

什么叫可重入锁_第3张图片

 以上只是部分内容,为了维护方便,本文已迁移到新地址:什么叫可重入锁 – 编程屋

你可能感兴趣的:(多线程,java)