Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why does this code produce deadlock? [duplicate]

class A {
    static final int i;
    static {
        i = 128;

        Thread t = new Thread() {
            public void run() {
                System.out.println("i=" + i);
            }
        };
        t.start();
        try {
           t.join();
        } catch (InterruptedException e) {
           Thread.currentThread().interrupt();
        }
    }
}
public class MainTesting {


    public static void main(String[] args) {
        A a = new A();
        System.out.println("finish");
    }
}

I never get finish get printed and value of i. Why is it so?

like image 317
Sunny Avatar asked Jun 21 '13 13:06

Sunny


People also ask

What is the main cause for deadlock Why?

Deadlock occurs when a set of processes are in a wait state, because each process is waiting for a resource that is held by some other waiting process. Therefore, all deadlocks involve conflicting resource needs by two or more processes.

How do you fix a deadlock problem?

Deadlock frequency can sometimes be reduced by ensuring that all applications access their common data in the same order - meaning, for example, that they access (and therefore lock) rows in Table A, followed by Table B, followed by Table C, and so on.

How can we avoid deadlock while updating SQL Server?

Update lock (U) is used to avoid deadlocks. Unlike the Exclusive lock, the Update lock places a Shared lock on a resource that already has another shared lock on it.

How can delete deadlock in SQL Server?

The only way to resolve a SQL Server deadlock is to terminate one of the processes and free up the locked resource so the process can complete. This occurs automatically when SQL Server detects a deadlock and kills off one of the competing processes (i.e., the victim).


1 Answers

You start off on thread 1 (the "main" thread), and start executing the static initializer for the A class.

Within that static initializer, you then start a new thread (2), which uses something within the A class. That means that thread 2 needs to wait until the A class has finished initilaizing before it will proceed, as per section 12.4.2 of the JLS:

If the Class object for C indicates that initialization is in progress for C by some other thread, then release LC and block the current thread until informed that the in-progress initialization has completed, at which time repeat this step.

However, your static initializer for A waits until thread 2 has completed (by calling join()) before it completes, leading to deadlock: the static initializer can't complete until thread 2 has completed, and thread 2 can't complete until the static initializer has completed...

Upshot: don't do this :)

like image 142
Jon Skeet Avatar answered Oct 31 '22 19:10

Jon Skeet