简体   繁体   中英

Am I understanding the concept of resource allocation correctly?

I am little confused about how synchronized works in Java for resource allocation. When I am given with the following code in 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.

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. and the node from R to P means that the process has lock on the resource.

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

Ahh, but that assumes that A is still running. 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. 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) {
   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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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