Threads em deadlock com classes iternas anônimas (exemplo para estudo)

Ola pessoal, quem havia me pedido um exemplo de deadlock de threads com classes internas anonimas da uma olhada nesse exemplo…

…mais simples que isso nao tem como…

Agora o desafio é fazer threads com classes internas anonimas…sem o deadlock…

// By: Adilson Bonan <arbonan@gmail.com>
// Deadlock.java

public class Deadlock {
    public static void main(String[] args) {
        
		// Nome simbólico para um recurso.
        final Object resource1 = "resource1";
        final Object resource2 = "resource2";
        
		// Primeira thread feita por objeto anônimo.
        Thread t1 = new Thread( ) {
                public void run( ) {
                    // Gera lock para recurso 1.
                    synchronized(resource1) {
                        System.out.println("Thread 1: locked resource 1");
                        
                        try { Thread.sleep(50); }
                        catch (InterruptedException e) {  }
                        
                        // Aguarda até obter o recurso 2.
                        synchronized(resource2) {
                            System.out.println("Thread 1: locked resource 2");
                        }
                    }
                }
            };
        
        // Primeira thread feita por objeto anônimo.
        Thread t2 = new Thread( ) {
                public void run( ) {
                    // Gera lock para recurso 1.
                    synchronized(resource2) {
                        System.out.println("Thread 2: locked resource 2");
                        
                        try { Thread.sleep(50); }
                        catch (InterruptedException e) {  }
                        
                        // O recurso 1 está em lock e agora temos um impasse
						// porque o recurso 2 está preso por essa thread.
                        synchronized(resource1) {
                            System.out.println("Thread 2: locked resource 1");
                        }
                    }
                }
            };
        
        // Inicia as duas threads e o programa nunca termina.
		// Ocorrencia de deadlock.
        t1.start( ); 
        t2.start( );
    }
}// Fim do programa.

Valezzzzzzzz

// By: Adilson Bonan <arbonan@gmail.com>
// Deadlock.java

public class Deadlock {
    public static void main(String[] args) {
        
		// Nome simbólico para um recurso.
        final Object resource1 = "resource1";
        final Object resource2 = "resource2";
        
		// Primeira thread feita por objeto anônimo.
        Thread t1 = new Thread( ) {
                public void run( ) {
                    // Gera lock para recurso 1.
                    synchronized(resource1) {
                        System.out.println("Thread 1: locked resource 1");
                        
                        try { Thread.sleep(50); }
                        catch (InterruptedException e) {  }
                        
                        // Aguarda até obter o recurso 2.
                        synchronized(resource2) {
                            System.out.println("Thread 1: locked resource 2");
                        }
                    }
                }
            };
        
        // Primeira thread feita por objeto anônimo.
        Thread t2 = new Thread( ) {
                public void run( ) {
                    // Gera lock para recurso 1.
                    synchronized(resource1) {
                        System.out.println("Thread 2: locked resource 2");
                        
                        try { Thread.sleep(50); }
                        catch (InterruptedException e) {  }
                        
                        // O recurso 1 está em lock e agora temos um impasse
						// porque o recurso 2 está preso por essa thread.
                        synchronized(resource2) {
                            System.out.println("Thread 2: locked resource 1");
                        }
                    }
                }
            };
        
        // Inicia as duas threads e o programa nunca termina.
		// Ocorrencia de deadlock.
        t1.start( ); 
        t2.start( );
    }
}// Fim do programa.