【多线程】奇奇怪怪的问题

多次start一个线程会怎么样

第二遍会报错Exception in thread "main" java.lang.IllegalThreadStateException

原因 threadStatus 初始值是0 跑过一次后是个非0的值 在第二遍就会报错

怎么查看服务器的死锁

java 死锁产生的四个必要条件:

  • 1、互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用
  • 2、不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。
  • 3、请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有。
  • 4、循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样就形成了一个等待环路。

方式一

jstack是java虚拟机自带的一种堆栈跟踪工具。jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息。

首先,我们通过jps确定当前执行任务的进程号:

//查看服务进程  还可以用 ps -aux |grep 名字 来查看的

[root@10 app]# jps
2848 jar
2942 Jps

// 这个命令来检测死锁

[root@10 app]# jstack -F 2848
Attaching to process ID 2848, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.333-b02
Deadlock Detection:

//找到死锁了

Found one Java-level deadlock:
=============================

"Thread-3":
waiting to lock Monitor@0x00007f0444005ea8 (Object@0x00000000f632b640, a java/lang/String),
which is held by "Thread-4"
"Thread-4":
waiting to lock Monitor@0x00007f04440062c8 (Object@0x00000000f632b610, a java/lang/String),
which is held by "Thread-2"
"Thread-2":
waiting to lock Monitor@0x00007f04440038d8 (Object@0x00000000f632b628, a java/lang/String),
which is held by "Thread-3"

Found a total of 1 deadlock.

//最后会打印死锁

Thread 2852: (state = BLOCKED)

- java.lang.Object.wait(long) @bci=0 (Interpreted frame)
- java.lang.ref.ReferenceQueue.remove(long) @bci=59, line=150 (Compiled frame)
- java.lang.ref.ReferenceQueue.remove() @bci=2, line=171 (Compiled frame)
- java.lang.ref.Finalizer$FinalizerThread.run() @bci=36, line=216 (Interpreted frame)


Thread 2851: (state = BLOCKED)

- java.lang.Object.wait(long) @bci=0 (Interpreted frame)
- java.lang.Object.wait() @bci=2, line=502 (Compiled frame)
- java.lang.ref.Reference.tryHandlePending(boolean) @bci=54, line=191 (Compiled frame)
- java.lang.ref.Reference$ReferenceHandler.run() @bci=1, line=153 (Interpreted frame)

方式二

使用arthas 执行 thread -b 可以检查死锁
执行后如果有死锁直接就输出详细信息了。

死锁代码示例

 private String lock1="lock1";
    private String lock2="lock2";
    private String lock3="lock3";


    public void test(){

        new Thread(()->{
            synchronized (lock1){

                System.out.println("占用了1锁 准备锁2");
                try {
                    TimeUnit.SECONDS.sleep(10);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                synchronized (lock2){
                    System.out.println("占用了1锁 占用锁2");
                }
            }
        }).start();

        new Thread(()->{
            synchronized (lock2){

                System.out.println("占用了2锁 准备锁3");
                try {
                    TimeUnit.SECONDS.sleep(10);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                synchronized (lock3){
                    System.out.println("占用了2锁 占用锁3");
                }
            }
        }).start();

        new Thread(()->{
            synchronized (lock3){

                System.out.println("占用了3锁 准备锁1");
                try {
                    TimeUnit.SECONDS.sleep(10);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                synchronized (lock1){
                    System.out.println("占用了3锁 占用锁1");
                }
            }
        }).start();
    }
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值