简体   繁体   English

我是否正确理解资源分配的概念?

[英]Am I understanding the concept of resource allocation correctly?

I am little confused about how synchronized works in Java for resource allocation. 我对同步在Java中如何进行资源分配感到困惑。 When I am given with the following code in Java: 当我得到以下Java代码时:

import java.util.concurrent.Semaphore;

public class Deadlock {
public Deadlock () {
    Semaphore mutex[] = new Semaphore[4];

    for (int i = 0; i < 4; i++) 
        mutex[i] = new Semaphore(1);

    A threadA = new A(mutex);
    B threadB = new B(mutex);
    C threadC = new C(mutex);

    threadA.start();
    threadB.start();
    threadC.start();
}

private class A extends Thread {
    private Semaphore[] resource;

    public A(Semaphore[] m) {
        resource = m;
    }

    public void run() {
        System.out.println("A started");
        synchronized( resouce[1] ) {
            System.out.println("A locks rsc 1");
            synchronized (resource[0]) {
                System.out.println("A locks rsc 0");
            }
        }
        System.out.println("A finished");
    }
}
private class B extends Thread {
    private Semaphore[] resource;

    public B(Semaphore[] m) {
        resource = m;
    }

    public void run() {
        System.out.println("B started");
        synchronized( resouce[3] ) {
            System.out.println("B locks rsc 3");
            synchronized (resource[0]) {
                System.out.println("B locks rsc 0");
                synchronized (resource[2]) {
                    System.out.println("B locks rsc 2");
                }
            }
        }
        System.out.println("B finished");
    }
}
private class C extends Thread {
    private Semaphore[] resource;

    public C(Semaphore[] m) {
        resource = m;
    }

    public void run() {
        System.out.println("C started");
        synchronized( resouce[2] ) {
            System.out.println("C locks rsc 2");
            synchronized (resource[1]) {
                System.out.println("C locks rsc 1");
            }
        }
        System.out.println("C finished");
    }
}
}

To my understanding, when thread A starts, thread A has lock on resource 1 and resource 0. Therefore, when Thread B starts, it will acquire lock on resource 3, but will be waiting on resource 0 to be released from Thread A. Since Thread B does not have a lock on resource 0, it will not be able to be wait on resource 2. When Thread C starts, it will have a lock on Resource 2, but also waiting on Resource 1 to be released from Thread A. 据我了解,当线程A启动时,线程A锁定了资源1和资源0。因此,当线程B启动时,它将获得对资源3的锁定,但将等待资源0从线程A释放。线程B在资源0上没有锁定,将无法在资源2上等待。线程C启动时,它将在资源2上具有锁定,但也等待资源1从线程A释放。

So, when its drawn out as resource allocation graph, it will look like the following: 因此,当将其绘制为资源分配图时,它将如下所示: 在此处输入图片说明

Here, where node from P to R refers to Process requesting for the resource. 这里,从P到R的节点是指对资源的请求处理。 and the node from R to P means that the process has lock on the resource. 从R到P的节点表示该进程已锁定资源。

Am I understanding this correctly? 我理解正确吗? Any help is welcome. 欢迎任何帮助。 Thank you. 谢谢。

when Thread B starts, it will acquire lock on resource 3, but will be waiting on resource 0 to be released from Thread A 线程B启动时,它将获取对资源3的锁定,但将等待资源0从线程A释放

Ahh, but that assumes that A is still running. 嗯,但是假设A仍在运行。 It might have finished already or it might not have even started yet. 它可能已经完成,甚至可能还没有开始。 The chances of you hitting the deadlock condition might only happen in 1 out of 1000s of run. 达到死锁状态的机会可能仅发生于运行的千分之一中。 This is the nature of threads that they run asynchronously, concurrently. 这就是线程异步并发运行的本质。 It is very hard to predict their precise behavior. 很难预测它们的精确行为。

In addition, you are complicating matters by calling System.out.println(...) which is doing synchronization as well. 另外,通过调用也正在同步的System.out.println(...)使事情变得复杂。 This throws off your test and changes the race conditions. 这将引发您的测试并改变比赛条件。

Am I understanding this correctly? 我理解正确吗?

I think you are understanding the resource graph appropriately, just not how hard it is to reach the perfect deadlock point at the right time. 我认为您正在适当地理解资源图,而不是在正确的时间达到完美的死锁点有多困难。

One thing to try would be to do the following in a while(true) loop. 要尝试的一件事是在while(true)循环中执行以下操作。

while (true) {
   A threadA = new A(mutex);
   B threadB = new B(mutex);
   C threadC = new C(mutex);
   threadA.start();
   threadB.start();
   threadC.start();
   threadA.join();
   threadB.join();
   threadC.join();
}

At some point the output will stop and the CPU will go to 0 and you will know that it has reached deadlock. 在某个时候,输出将停止,CPU将变为0,您将知道它已经达到死锁状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM