使用Timeout避免Java多线程中的死锁 [英] Using Timeout to avoid deadlock in Java multithreading

查看:353
本文介绍了使用Timeout避免Java多线程中的死锁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

避免Java多线程中死锁情况的策略之一是使用超时。
假设,一个线程已经获得了对一个资源的锁定,现在正在等待锁定另一个资源。经过一段时间后,如果无法获取资源2的锁定,则应该停止等待资源2上的锁定。它也应该释放对resource1的锁定。因此,将避免死锁。

One of the strategy to avoid deadlock situation in Java Multithreading is using timeout. Suppose, one thread has acquired lock on one resource and now waiting for lock on another resource. After certain time period if it can not acquire lock on resource2 then it should stop waiting for lock on resource2. Also it should release lock on resource1. Thus deadlocks will be avoided.

但是如何在Java中实现它?如何明确释放锁定?如何定义等待锁的超时。

But how to implement it in Java ? How to explicitly "release" lock ? How to define timeout to wait for lock.

什么是精确的java命令和语法。有什么问候世界的例子吗?

What is exact java commands and syntax. Any hello-worldish example please ?

推荐答案

这是一个设计的例子,有2个锁和2个线程试图在不同的地方获取它们命令。没有超时,代码就会死锁。

Here is a contrived example with 2 locks and 2 threads that try to acquire them in different orders. Without the timeout, the code would deadlock.

public static void main(String[] args) throws Exception {
    final ReentrantLock lock1 = new ReentrantLock();
    final ReentrantLock lock2 = new ReentrantLock();
    Runnable try1_2 = getRunnable(lock1, "lock 1", lock2, "lock 2");
    Runnable try2_1 = getRunnable(lock2, "lock 2", lock1, "lock 1");
    new Thread(try1_2).start();
    new Thread(try2_1).start();
}

private static Runnable getRunnable(final ReentrantLock lock1, final String lock1Name, final ReentrantLock lock2, final String lock2Name) {
    return new Runnable() {
        @Override
        public void run() {
            try {
                if (lock1.tryLock(1, TimeUnit.SECONDS)) {
                    System.out.println(lock1Name + " acquired in thread " + Thread.currentThread());
                    if (lock2.tryLock(1, TimeUnit.SECONDS)) {
                        System.out.println(lock2Name + " acquired in thread " + Thread.currentThread());
                        Thread.sleep(2000);
                    } else {
                        System.out.println("Could not acquire "+lock2Name + " in thread " + Thread.currentThread());
                        lock1.unlock();
                        System.out.println(lock1Name + " released in thread " + Thread.currentThread());
                    }
                } else {
                    System.out.println("Could not acquire " + lock1Name + " in thread " + Thread.currentThread());
                }
            } catch (InterruptedException e) {
                //you should not ignore it
            } finally {
                if (lock1.isHeldByCurrentThread()) lock1.unlock();
                if (lock2.isHeldByCurrentThread()) lock2.unlock();
            }
        }
    };
}

这篇关于使用Timeout避免Java多线程中的死锁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆