您当前的位置: 首页 >  Java

小志的博客

暂无认证

  • 0浏览

    0关注

    1217博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Java并发多线程编程——重入锁

小志的博客 发布时间:2021-04-16 22:04:47 ,浏览量:0

参考:https://blog.csdn.net/w8y56f/article/details/89554060

目录
    • 一、重入锁的理解
    • 二、方式一:使用synchronized演示例重入锁示例
    • 三、方式二:使用ReentrantLock演示例重入锁示例
    • 四、使用ReentrantLock演示例重入锁示例(加锁和释放次数不一样导致的死锁)

一、重入锁的理解
  • 某个线程已经获得某个锁,可以再次获取锁而不会出现死锁。
  • 可重入锁,也叫做递归锁。指的是同一线程外层函数获得锁之后,内层递归函数仍然能够获得该锁的代码。
  • 在同一个线程,在外层方法获取锁的时候,进入内层方法时会自动获取锁。
  • synchronized和ReentrantLock都是可重入的。
  • 可重入锁最大的作用就是避免死锁。
  • 重入降低了编程复杂性。
二、方式一:使用synchronized演示例重入锁示例

1、代码

package com.xz.thread.t5;

/**
 * @description: 第一种方式:使用synchronized演示例重入锁
 * @author: xz
 */
public class Demo3 {
    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();
    }
}

2、输出结果 在这里插入图片描述 3、结论

  • 由第2步截图可知,没有发生死锁,可以多次获取相同的锁。
三、方式二:使用ReentrantLock演示例重入锁示例

1、使用ReentrantLock的注意点

  • ReentrantLock 和 synchronized 不一样,需要手动释放锁,所以使用 ReentrantLock的时候一定要手动释放锁,并且加锁次数和释放次数要一样。

2、代码

package com.xz.thread.t5;

import java.util.concurrent.locks.ReentrantLock;

/**
 * @description: 第一种方式:使用ReentrantLock演示例重入锁
 * @author: xz
 */
public class Demo4 {
    public static void main(String[] args) {
        ReentrantLock reentrantLock = new ReentrantLock();

        new Thread(new Runnable() {
            @Override
            public void run() {
                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();
    }
}

3、输出结果 在这里插入图片描述 4、结论

  • 由第3步截图可知,没有发生死锁,可以多次获取相同的锁。
四、使用ReentrantLock演示例重入锁示例(加锁和释放次数不一样导致的死锁)

1、代码

package com.xz.thread.t5;

import java.util.Random;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @description: 使用ReentrantLock演示例重入锁(加锁和释放次数不一样导致的死锁)
 * @author: xz
 */
public class Demo5 {
    public static void main(String[] args) {
        ReentrantLock reentrantLock = new ReentrantLock();
        //第一个线程
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    reentrantLock.lock();
                    System.out.println("第1次获取锁,这个锁是:" + reentrantLock);

                    int index = 1;
                    while (true) {
                        try {
                            reentrantLock.lock();
                            System.out.println("第" + (++index) + "次获取锁,这个锁是:" + reentrantLock);
                            try {
                                Thread.sleep(new Random().nextInt(200));
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            if (index == 10) {
                                break;
                            }
                        } finally {
                            //lock.unlock();// 这里故意注释,实现加锁次数和释放次数不一样
                        }
                    }
                } finally {
                    reentrantLock.unlock();
                }
            }
        }).start();

        //第二个线程
        new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    reentrantLock.lock();
                    for (int i = 0; i             
关注
打赏
1661269038
查看更多评论
0.0408s