JUC(7) 锁

1. 公平锁和非公平锁

概念

  • 公平锁:非常公平,线程之间不可以插队
  • 非公平锁:非常不公平,线程之间可以插队(默认)
    比如2ms能比20ms先执行

Lock锁源码:

	//无参构造: 默认非公平锁
	/**
     * Creates an instance of {@code ReentrantLock}.
     * This is equivalent to using {@code ReentrantLock(false)}.
     */
    public ReentrantLock() {
        sync = new NonfairSync();
    }


 	// 有参构造 传入true,则是公平锁
	/**
     * Creates an instance of {@code ReentrantLock} with the
     * given fairness policy.
     *
     * @param fair {@code true} if this lock should use a fair ordering policy
     */
    public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }

2. 可重入锁

概念

  • 又称递归锁,拿到了外边的锁,调用里边上锁的方法,就可以自动获得里面的锁。此时外边的锁也不会释放
  • 执行完全部的锁(外部 + 内部又调用方法加的锁)才会释放最外边的锁,其他线程才能拿到最外层的锁

3. 自旋锁

概述

  • AtomicXxx类下的CAS方法底层就是自旋锁,不断循环直到成功为止
  • 自旋锁主要应用CAS操作,直到手动释放锁才停止

4. 死锁

概念

  • 死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
  • 两个线程互相抢夺资源,互相争用还未释放的锁
package com.lin;

import java.util.concurrent.TimeUnit;

public class demoJUC3 {
    public static void main(String[] args) {

        MyThread thread = new MyThread("xiao","si");

        new Thread(()->{
            // 线程1 对资源A 上锁,而且想得到 资源B的锁
            synchronized (thread.getA()){
                System.out.println("线程1锁住了A");

                // 延迟,保证 线程2 先拿到 B
                try {
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (thread.getB()){

                }
            }
        },"Thread-1").start();

        new Thread(()->{
            // 线程2 先对资源B上锁,而且想得到 资源A的锁
            synchronized (thread.getB()){
                System.out.println("线程2锁住了B");
                synchronized (thread.getA()){

                }
            }
        },"Thread-2").start();

    }
}

/**
 * 资源类
 */

class MyThread {


    private String A;
    private String B;

    public MyThread(String a, String b) {
        A = a;
        B = b;
    }

    public String getA() {
        return A;
    }

    public String getB() {
        return B;
    }
}


/**
 * 输出
 * 线程1锁住了A
 * 线程A锁住了B 进入死锁
 **/

5.排查死锁

方法

使用命令 jps -l 定位进程号
在这里插入图片描述

使用jstack 进程号 查看堆栈信息

在这里插入图片描述
使用jstat -gc 进程号 查看JVM内部gc的信息
在这里插入图片描述

  • S0C:第一个幸存区的大小,单位KB
  • S1C:第二个幸存区的大小
  • S0U:第一个幸存区的使用大小
  • S1U:第二个幸存区的使用大小
  • EC:伊甸园区的大小
  • EU:伊甸园区的使用大小
  • OC:老年代大小
  • OU:老年代使用大小
  • MC:方法区大小
  • MU:方法区使用大小
  • CCSC: 压缩类空间大小
  • CCSU: 压缩类空间使用大小
  • YGC:年轻代垃圾回收次数
  • YGCT:年轻代垃圾回收消耗时间 ,单位s
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间,单位s
  • GCT:垃圾回收消耗总时间,单位s
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值