JUC学习5(锁)

1.锁的八种状态

2.公平锁和非公平锁

3.可重入锁的介绍(synchronized和lock)

4.死锁

锁的八种状态

锁的八种状态由这3种情况组合而成

1.对于普通的同步方法,锁的是当前的实例对象就是this

    /**
     * 对于普通的同步方法,锁的是当前的实例对象就是this
     */
    public synchronized void hello1(){
        System.out.println("hello");
    }

2.对于静态同步方法,锁的是当前的Class对象

    /**
     * 对于静态同步方法,锁的是当前的Class对象
     * @throws InterruptedException
     */
    public static synchronized void hello() throws InterruptedException {

        TimeUnit.SECONDS.sleep(4);
        System.out.println("hello");
    }

3.对于同步方法块,锁的时Synchronized括号里配置的对象

    /**
     * 对于同步方法块,锁的时Synchronized括号里配置的对象,对于当前来说就是this----->synchronized (this)
     */
    public void hello3(){
        synchronized (this){
            System.out.println("hello");
        }
    }

公平锁和非公平锁

非公平锁会提升效率,但可能会使线程一直拿不到锁饿死(线程长时间得不到资源从而一直得不到执行)

公平锁:多个线程按照申请锁的顺序进入队列,从而的到锁

 ReentrantLock默认是非公平锁

public ReentrantLock() {
        sync = new NonfairSync();
    }

可重入锁

使用synchronized来验证可重入锁

 public synchronized void add(){
        add();
    }

而它报错的内容为堆栈溢出,但说明了它是可重入锁

 而对于Lock来说

    public void get(){
        try {

            LOCK.lock();
            System.out.println(Thread.currentThread().getName()+"我在外层");


            try {
                LOCK.lock();
                System.out.println(Thread.currentThread().getName()+"我在内层");
            }finally {
                LOCK.unlock();
            }

        }finally {
            LOCK.unlock();
        }
    }

结果可以打印出来,说明Lock也是可重入锁

死锁

死锁的产生是多个线程互相持有资源得不到释放

下面来具体演示一下

线程aa持有o1,想要获取o2

线程bb持有o2,想要获取o1

代码:

        Object o1 = new Object();
        Object o2 = new Object();
        new Thread(()->{
            synchronized (o1){
                System.out.println("线程"+Thread.currentThread().getName()+"持有o1,想要得到o2");
                synchronized (o2){
                    System.out.println("获取o2");
                }
            }
        },"aa").start();

        new Thread(()->{
            synchronized (o2){
                System.out.println("线程"+Thread.currentThread().getName()+"持有o2,想要得到o1");
                synchronized (o1){
                    System.out.println("获取o1");
                }
            }
        },"bb").start();

运行结果如图所示,程序一直没有

但这个可能也不是死锁,比如死循环,或者睡眠也有一样的结果,即我们只有两个工具jps和jstack(必须配置环境变量)

使用jps获取到当前类的进程号 jps -l

 我的类是demo11,从而进程号为20244

 使用这个命令 jstack 20244,在最后的结果处就有相应的显示

 Found 1 deadlock. 发现一个死锁,即从而确定死锁

 如果需要这个demo,就来获取:https://gitee.com/wuwenlei/annotation-development/blob/dev/spring-annotation/src/main/java/com/springannotation/sync/demo11.java

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值