• 技术文章 >Java >java教程

    如何解决java中的死锁问题

    VV2019-11-28 16:33:17转载1060

    一、死锁的定义

    死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。

    那么我们换一个更加规范的定义:集合中的每一个进程都在等待只能由本集合中的其他进程才能引发的事件,那么该组进程是死锁的。

    免费视频教程推荐:java免费视频教程

    二、Java 代码模拟死锁

    代码示例:

    /**
     * 模拟死锁类
     * */
    public class ImitateDeadLock {
    	public static void main(String[] args) {
    		final Object a=new Object();
    		final Object b=new Object();
    		//线程 threadA 获取对象 a 的锁之后,休眠10秒, 尝试获取对象 b 的锁
    		Thread threadA=new Thread(new Runnable() {
    			@Override
    			public void run() {
    				synchronized (a) {
    						System.out.println("threadA 获取到对象 a 的锁");
    						try {
    							Thread.sleep(10000);
    							synchronized (b) {
    								System.out.println("threadA 获取到对象 b 的锁");
    							}
    						} catch (InterruptedException e) {
    							e.printStackTrace();
    						}
    						
    					
    				}
    			}
    		});
    		//线程 threadB 获取对象 b 的锁之后,休眠10秒, 尝试获取对象 a 的锁
    		Thread threadB=new Thread(new Runnable() {
    			@Override
    			public void run() {
    				synchronized (b) {
    						System.out.println("threadB 获取到对象 b 的锁");
    						try {
    							Thread.sleep(10000);
    							synchronized (a) {
    								System.out.println("threadB 获取到对象 a 的锁");
    							}
    						} catch (InterruptedException e) {
    							e.printStackTrace();
    						}
    				}
    			}
    		});
    		
    		threadA.start();
    		
    		threadB.start();
    	}
    }

    运行结果:

    threadA 获取到对象 a 的锁
    threadB 获取到对象 b 的锁
    无限等待........

    三、如何解决

    1、确认问题

    (1)Jps + Jstack 命令

    Jps : 查看当前进程

    如下所示, class 名称为 ImitateDeadLock 的进程为我们需要查看的进程。

    C:\Users\31415> jps
    1256 ImitateDeadLock
    9240 Jps
    7548 org.eclipse.equinox.launcher_1.3.100.v20150511-1540.jar

    jstack : 查看堆栈信息

    执行 jstack 命令后,会显示出两个线程互相等待,产生了死锁。

    C:\Users\31415>jstack 1256
    Java stack information for the threads listed above:
    ===================================================
    "Thread-1":
            at ImitateDeadLock$2.run(ImitateDeadLock.java:37)
            - waiting to lock <0x048b15a8> (a java.lang.Object)
            - locked <0x048b15b0> (a java.lang.Object)
            at java.lang.Thread.run(Thread.java:745)
    "Thread-0":
            at ImitateDeadLock$1.run(ImitateDeadLock.java:17)
            - waiting to lock <0x048b15b0> (a java.lang.Object)
            - locked <0x048b15a8> (a java.lang.Object)
            at java.lang.Thread.run(Thread.java:745)
    
    Found 1 deadlock.

    2、处理问题

    (1)确定的顺序获取锁

    例如:我们上面的 Demo 中,两个线程获取锁的顺序都为 先获取对象 a 的锁,在获取对象 b 的锁,就不会出现死锁的问题。

    (2)超时放弃

    当使用synchronized关键词提供的内置锁时,只要线程没有获得锁,那么就会永远等待下去,然而Lock接口提供了boolean tryLock(long time, TimeUnit unit) throws InterruptedException方法,该方法可以按照固定时长等待锁,因此线程可以在获取锁超时以后,主动释放之前已经获得的所有的锁。通过这种方式,也可以很有效地避免死锁。

    想了解更多相关教程请访问:java入门学习

    以上就是如何解决java中的死锁问题的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:CSDN,如有侵犯,请联系admin@php.cn删除
    专题推荐:java 死锁
    上一篇:java类型擦除真的能完全擦除一切信息吗? 下一篇:搞定多个java版本的灵活切换和管理
    大前端线上培训班

    相关文章推荐

    • java中如何实现重建二叉树• java、javac、javadoc、jar之间的区别• java中什么情况下使用ArrayList和LinkedList?• java中的装箱与拆箱

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网