多线程——多线程debug调试(非常非常详细的调试)

在日常开发中我们经常会遇到多线程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();
        }


    }
}

多线程——多线程debug调试(非常非常详细的调试)_第1张图片

开始刚一执行此时i=2

多线程——多线程debug调试(非常非常详细的调试)_第2张图片

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

 

再次运行

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

多线程——多线程debug调试(非常非常详细的调试)_第3张图片

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

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

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

多线程——多线程debug调试(非常非常详细的调试)_第4张图片 改为Thread之后---->makeDefault---->done

此时就Ok了

多线程——多线程debug调试(非常非常详细的调试)_第5张图片

F8

多线程——多线程debug调试(非常非常详细的调试)_第6张图片

多线程——多线程debug调试(非常非常详细的调试)_第7张图片

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

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

多线程——多线程debug调试(非常非常详细的调试)_第8张图片

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

多线程——多线程debug调试(非常非常详细的调试)_第9张图片

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

线程1和2都在等待资源

多线程——多线程debug调试(非常非常详细的调试)_第10张图片

接下来看ReetrantLock 的执行过程

重新启动

多线程——多线程debug调试(非常非常详细的调试)_第11张图片

此时3个线程都停留在这

多线程——多线程debug调试(非常非常详细的调试)_第12张图片

此时跳入inCreat方法

多线程——多线程debug调试(非常非常详细的调试)_第13张图片

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

多线程——多线程debug调试(非常非常详细的调试)_第14张图片 F8首先执行CAS

多线程——多线程debug调试(非常非常详细的调试)_第15张图片

其他线程就不会执行

多线程——多线程debug调试(非常非常详细的调试)_第16张图片 多线程——多线程debug调试(非常非常详细的调试)_第17张图片

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

接下来看线程1

多线程——多线程debug调试(非常非常详细的调试)_第18张图片

 多线程——多线程debug调试(非常非常详细的调试)_第19张图片

多线程——多线程debug调试(非常非常详细的调试)_第20张图片

多线程——多线程debug调试(非常非常详细的调试)_第21张图片

 之后执行acquire方法

多线程——多线程debug调试(非常非常详细的调试)_第22张图片

多线程——多线程debug调试(非常非常详细的调试)_第23张图片

再跳

多线程——多线程debug调试(非常非常详细的调试)_第24张图片

多线程——多线程debug调试(非常非常详细的调试)_第25张图片

多线程——多线程debug调试(非常非常详细的调试)_第26张图片

多线程——多线程debug调试(非常非常详细的调试)_第27张图片

多线程——多线程debug调试(非常非常详细的调试)_第28张图片

跳进去

多线程——多线程debug调试(非常非常详细的调试)_第29张图片

多线程——多线程debug调试(非常非常详细的调试)_第30张图片

多线程——多线程debug调试(非常非常详细的调试)_第31张图片

此时addWaiter执行完毕

多线程——多线程debug调试(非常非常详细的调试)_第32张图片

接着执行acquireQueued方法

多线程——多线程debug调试(非常非常详细的调试)_第33张图片

多线程——多线程debug调试(非常非常详细的调试)_第34张图片 多线程——多线程debug调试(非常非常详细的调试)_第35张图片

多线程——多线程debug调试(非常非常详细的调试)_第36张图片

同理线程2也这样

多线程——多线程debug调试(非常非常详细的调试)_第37张图片

多线程——多线程debug调试(非常非常详细的调试)_第38张图片

执行tryRelease方法

多线程——多线程debug调试(非常非常详细的调试)_第39张图片

多线程——多线程debug调试(非常非常详细的调试)_第40张图片 多线程——多线程debug调试(非常非常详细的调试)_第41张图片

tryRelease方法执行成功

多线程——多线程debug调试(非常非常详细的调试)_第42张图片

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

多线程——多线程debug调试(非常非常详细的调试)_第43张图片

多线程——多线程debug调试(非常非常详细的调试)_第44张图片

多线程——多线程debug调试(非常非常详细的调试)_第45张图片

该线程执行完毕

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

多线程——多线程debug调试(非常非常详细的调试)_第46张图片

 

你可能感兴趣的:(MutiThread)