在日常开发中我们经常会遇到多线程Debug调试,

一般我们都是利用Spring Boot对外提供接口,Tomcat中在有多人同时访问时,会开启多线程,但是,这时有可能发生异常。

说明接口在多线程访问中不是很稳定,这时就要利用多线程的Debug调试。

以下是一个小Demo来演示多线程的Debug调试

public class LockDemoReetrantLock {
    private int i=0;
    private ReentrantLock reentrantLock=new ReentrantLock();
    public void inCreate(){
     断点   reentrantLock.lock();

        try{
            i++;
        }finally {
            reentrantLock.unlock();//注意:一般的释放锁的操作都放到finally中,
            // 多线程可能会出错而停止运行,如果不释放锁其他线程都不会拿到该锁
        }

    }


    public static void main(String[] args){
        ReentrantLock lock = new ReentrantLock();
        lock.lock();
        LockDemoReetrantLock lockDemoReetrantLock = new LockDemoReetrantLock();
        for (int i=0;i<3;i++){
            new Thread(()->{
                lockDemoReetrantLock.inCreate();
            }).start();
        }


    }
}

java多线程调优 java多线程调试_i++

开始刚一执行此时i=2

java多线程调优 java多线程调试_Lock_02

接着下一步下一步,程序直接跳出 看不到ReentrantLock的排队操作,

再次运行

在进行一次调试此时i=1

java多线程调优 java多线程调试_bug调试_03

同样看不到排队操作,不是我们想要的结果!!

在断点调试的断点上右击实现设置(Mac版)

一运行Debug 其它两个线程就已经启动了,中有一个线程能够停止到这个断点

java多线程调优 java多线程调试_bug调试_04

改为Thread之后---->makeDefault---->done

此时就Ok了

java多线程调优 java多线程调试_Lock_05

F8

java多线程调优 java多线程调试_多线程_06

java多线程调优 java多线程调试_Lock_07

接下来我们看第二个线程是否获得锁

点入该线程(012线程顺序是随机的)

java多线程调优 java多线程调试_bug调试_08

F8显示未挂起的线程不可用 该线程没能获取到该锁(同理Thread2也不能获取该锁)

java多线程调优 java多线程调试_i++_09

线程1和2 wait 线程0和主线程running

线程1和2都在等待资源

java多线程调优 java多线程调试_java多线程调优_10

接下来看ReetrantLock 的执行过程

重新启动

java多线程调优 java多线程调试_java多线程调优_11

此时3个线程都停留在这

java多线程调优 java多线程调试_bug调试_12

此时跳入inCreat方法

java多线程调优 java多线程调试_i++_13

再条进到lock方法中去  进入到非公平锁的实现

java多线程调优 java多线程调试_java多线程调优_14

F8首先执行CAS

java多线程调优 java多线程调试_i++_15

其他线程就不会执行

java多线程调优 java多线程调试_多线程_16

 

java多线程调优 java多线程调试_i++_17

 此时由于是线程0先执行的,我们再开一下线程1(012执行顺序是随机的这里假定0先执行)

接下来看线程1

java多线程调优 java多线程调试_Lock_18

 

java多线程调优 java多线程调试_bug调试_19

java多线程调优 java多线程调试_Lock_20

java多线程调优 java多线程调试_bug调试_21

 之后执行acquire方法

java多线程调优 java多线程调试_Lock_22

java多线程调优 java多线程调试_i++_23

再跳

java多线程调优 java多线程调试_java多线程调优_24

java多线程调优 java多线程调试_Lock_25

java多线程调优 java多线程调试_Lock_26

java多线程调优 java多线程调试_Lock_27

java多线程调优 java多线程调试_Lock_28

跳进去

java多线程调优 java多线程调试_Lock_29

java多线程调优 java多线程调试_java多线程调优_30

java多线程调优 java多线程调试_i++_31

此时addWaiter执行完毕

java多线程调优 java多线程调试_多线程_32

接着执行acquireQueued方法

java多线程调优 java多线程调试_java多线程调优_33

java多线程调优 java多线程调试_java多线程调优_34

java多线程调优 java多线程调试_java多线程调优_35

java多线程调优 java多线程调试_i++_36

 

java多线程调优 java多线程调试_bug调试_37

java多线程调优 java多线程调试_java多线程调优_38

同理线程2也这样

java多线程调优 java多线程调试_bug调试_39

java多线程调优 java多线程调试_多线程_40

执行tryRelease方法

java多线程调优 java多线程调试_java多线程调优_41

java多线程调优 java多线程调试_i++_42

 

java多线程调优 java多线程调试_java多线程调优_43

tryRelease方法执行成功

java多线程调优 java多线程调试_i++_44

执行完成之后就会唤醒其他线程

java多线程调优 java多线程调试_i++_45

java多线程调优 java多线程调试_java多线程调优_46

java多线程调优 java多线程调试_i++_47

该线程执行完毕

接着查看其他线程(1,2)

java多线程调优 java多线程调试_bug调试_48