学习笔记(03):Java并发编程精讲-线程死锁和避免

立即学习:https://edu.csdn.net/course/play/26270/326861?utm_source=blogtoedu

1、避免死锁

  • 不使用锁,不使用2把及以上的锁
  • 必须使用2把及以上锁的时候,确保在整个应用程序中对获取锁的顺序是一致的
  • 尝试获取具有超时释放的锁时,例如Locak中的tryLock来获取锁
  • 当发生了java-level锁时,重启程序来干掉进程/线程
    package test;
    
    public class DemoLocak {
    
    	private static final Object lock1 = new Object();
    	private static final Object lock2 = new Object();
    
    	public static void main(String[] args) {
    		newThread("ThreadA", lock1, lock2).start();
    
    		newThread("ThreadB", lock2, lock1).start();
    //改成以下情况不会造成死锁,满足第2种情况
    //newThread("ThreadB", lock1, lock2).start();
    
    	}
    
    	private static Thread newThread(String threadName, Object lockFrist, Object lockSecond) {
    		return new Thread(() -> {
    			synchronized (lockFrist) {
    				System.out.println(Thread.currentThread().getName() + " holiding lockFrist!");
    				System.out.println(threadName + " holiding!");
    				try {
    					Thread.sleep(300L);
    				} catch (InterruptedException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    				System.out.println(threadName + " waitting  lockFrist!");
    				synchronized (lockSecond) {
    					System.out.println(threadName + " holiding lockSecond!");
    				}
    			}
    		}, threadName);
    	}
    }
    

    2、定位死锁问题

  • jps 例举正在运行的虚拟机进程并显示虚拟机执行的主类以及这些进程的唯一ID(PID)

  • jstack  用于JVN当前时刻的线程快走,得到JVM当前每一条线程正在执行的堆栈信息,定位线程长时间卡顿问题,如死锁、死循环等问题
  • 运行程序,在terminal输入jps查看目前所有的线程,查看目前是否有阻塞的线程。第二,输入 jstack 进程id,查看当前进程详情的堆栈信息   jstack 进程id(阻塞进程id)

3、处理数据库的死锁问题

死锁情景:

  • 针对同一张表
  • 开启2个会话,每个会话调用 start tran
  • 第一个会话先更新id=1的行
  • 第二个会话先更新id=2的行
  • 第一个会话先更新id=2的行,此时等待id=2行的锁
  • 第二个会话更新id=1的行,此时数据库检测死锁,种植触发死锁的事务,第一个会话的等待状态变为正常状态
  • 调用“commit”提交第一个会话事务,数据成功

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值