Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-如何检测死锁并从中恢复?_Java_Multithreading_Synchronization_Deadlock_Synchronized - Fatal编程技术网

Java-如何检测死锁并从中恢复?

Java-如何检测死锁并从中恢复?,java,multithreading,synchronization,deadlock,synchronized,Java,Multithreading,Synchronization,Deadlock,Synchronized,现在我编写了一个Java程序,其目的是检测死锁并从这种情况中恢复。程序输入是两个数字,N=资源类型的数量,M=进程的数量 我想做这样的事情: private static void test2() { final ReentrantLock lock1 = new ReentrantLock(); final ReentrantLock lock2 = new ReentrantLock(); Thread thread1 = new Thread(new Runnab

现在我编写了一个Java程序,其目的是检测死锁并从这种情况中恢复。程序输入是两个数字,N=资源类型的数量,M=进程的数量

我想做这样的事情:

private static void test2() {
    final ReentrantLock lock1 = new ReentrantLock();
    final ReentrantLock lock2 = new ReentrantLock();

    Thread thread1 = new Thread(new Runnable() {
        @Override public void run() {
            try {
                lock1.lock();
                System.out.println("Thread1 acquired lock1");
                try {
                    TimeUnit.MILLISECONDS.sleep(50);
                } catch (InterruptedException ignore) {}
                lock2.lock();
                System.out.println("Thread1 acquired lock2");
            }
            finally {
                lock2.unlock();
                lock1.unlock();
            }
        }
    });
    thread1.start();

    Thread thread2 = new Thread(new Runnable() {
        @Override public void run() {
            try {
                lock2.lock();
                System.out.println("Thread2 acquired lock2");
                try {
                    TimeUnit.MILLISECONDS.sleep(50);
                } catch (InterruptedException ignore) {}
                lock1.lock();
                System.out.println("Thread2 acquired lock1");
            }
            finally {
                lock1.unlock();
                lock2.unlock();
            }
        }
    });
    thread2.start();

    // Wait a little for threads to deadlock.
    try {
        TimeUnit.MILLISECONDS.sleep(100);
    } catch (InterruptedException ignore) {}

    detectDeadlock();
}  
但是不是2,N锁,我有几个问题要解决。下面是我的代码和我的尝试:

class Main {
    private static int MAX_AVAILABLE = 10;
    private static int IDLE = 1000;

    public static void main(String[] args) throws java.lang.Exception{
        int n, m; //number of resources and process, respectively
        ReentrantLock[] resources; // Locks for resources
        int[] available; // Number of instances per resource
        Process[] processes; // Processes array
        DeadlockDetector supervisor; // Deadlock detaction class

        n = Integer.valueOf(args[0]);
        m = Integer.valueOf(args[1]);

        resources = new ReentrantLock[n];
        available = new int[n];
        processes = new Process[m];
        supervisor = new DeadlockDetector();

        // Create resources array
        for(int i=0; i<n; ++i){
            available[i] = (int)(Math.floor(Math.random()*MAX_AVAILABLE + 1));
            resources[i] = new ReentrantLock();
            System.out.println("R"+String.valueOf(i+1)+"-> instances: "+String.valueOf(available[i]));
        }

        // Creating processes
        for(int i=0; i<m; ++i){
            processes[i] = new Process(i, resources, available, n);
            System.out.println("P"+String.valueOf(i+1)+"-> requested "+Arrays.toString(processes[i].requested));
            processes[i].start();
        }
        //Run deadlock detection
        try {
            TimeUnit.MILLISECONDS.sleep(IDLE);
        }catch (InterruptedException ignore){}

        supervisor.start();
     }
}
class Process extends Thread{
    public int id;
    public int total; // Total of resources instances needed for finished the process
    public ReentrantLock[] resources;
    public int[] requested; // Number of instances needed per resource type
    public boolean[] needed; // Boolean indicating whether the process needs at least one instance of the resource i 
    public int n;
    private static int MIN_TIME = 1000;
    private static int MAX_TIME = 3000;

    public Process(int index, ReentrantLock[] res, int[] available, int n_resources){
       id = index;
       n = n_resources;
       resources = res;

       total = 0; 
       requested = new int[n];
       needed = new boolean[n];

       for(int i=0; i<n; ++i){
            requested[i] = (int)(Math.floor(Math.random()*available[i]));
            needed[i] = requested[i] > 0;
            total += requested[i];
       }
    }

    @Override
    public void run(){
        int resourceT = 0;
        int timeToSleep;

        System.out.println("P"+String.valueOf(id+1)+" begin running");
        try{
            while(total > 0){
                resourceT = (int)(Math.floor(Math.random()*n));
                if(requested[resourceT] < 1){
                    System.out.println("P"+String.valueOf(id+1)+"-> I do not need more R"+String.valueOf(resourceT+1));
                    continue;
                }
                System.out.println("P"+String.valueOf(id+1)+"-> I'll take R"+String.valueOf(resourceT+1));
                resources[resourceT].lock();
                timeToSleep = (int)(Math.floor(Math.random()*(MAX_TIME - MIN_TIME)) + MIN_TIME);
                try{
                    TimeUnit.MILLISECONDS.sleep(timeToSleep);
                }catch (InterruptedException ignore){}
                --total;
                --requested[resourceT];
            }
        }finally{
            for(int i=0; i<n; ++i){
                if(needed[i] && resources[i].isHeldByCurrentThread())
                    resources[i].unlock();
            }
        }
        System.out.println("P"+String.valueOf(id+1)+"-> Im finished");
    }
}

class DeadlockDetector extends Thread{
    public ThreadMXBean threadBean;
    public long[] threadIds;

    public DeadlockDetector(){
    }

    @Override
    public void run(){
        Boolean good;
        this.threadBean = ManagementFactory.getThreadMXBean();

        threadIds = threadBean.findDeadlockedThreads();
        int deadlockedThreads = threadIds != null? threadIds.length : 0;

        if(deadlockedThreads>1){
            good = false;
            System.out.println("Number of deadlocked threads: " + deadlockedThreads);
            //recoverDeadlock();
            //break;
        }
}
public void recoverDeadlock(){
}
}
主类{
专用静态int MAX_可用=10;
专用静态int IDLE=1000;
公共静态void main(字符串[]args)引发java.lang.Exception{
int n,m;//分别为资源和进程的数量
ReentrantLock[]资源;//资源的锁
int[]可用;//每个资源的实例数
进程[]进程;//进程数组
死锁检测器监视器;//死锁检测类
n=整数.valueOf(args[0]);
m=整数.valueOf(args[1]);
资源=新的可重入锁[n];
可用=新整数[n];
流程=新流程[m];
主管=新的死锁检测器();
//创建资源数组
对于(int i=0;i 0){
resourceT=(int)(Math.floor(Math.random()*n));
如果(请求[资源]<1){
System.out.println(“P”+String.valueOf(id+1)+“->我不需要更多的R”+String.valueOf(resourceT+1));
继续;
}
System.out.println(“P”+String.valueOf(id+1)+“->我将取R”+String.valueOf(resourceT+1));
resources[resourceT].lock();
timeToSleep=(int)(Math.floor(Math.random()*(MAX\u TIME-MIN\u TIME))+MIN\u TIME);
试一试{
TimeUnit.ms.sleep(timeToSleep);
}捕获(中断异常忽略){}
--总数;
--请求[资源];
}
}最后{
对于(int i=0;i1){
好=假;
System.out.println(“死锁线程数:“+死锁线程”);
//恢复死锁();
//中断;
}
}
公共无效恢复死锁(){
}
}

请问,有人能帮我解决这个细节吗?谢谢

“但是不是2个锁,而是N个锁,我在这方面有几个问题。”-那么问题是什么?它是如何工作的?因为线程永远不会在没有死锁时结束@StephenCI感觉到问题是在finally块中解锁时发生的,因为在一些没有死锁发生的运行中,线程不会结束。那么您是说问题在
test2()
类中,而不是死锁检测器中?