Thread.currentThread().join();?

Pessoal, estou com dificuldades de entender este código o resultado deste código é “GoInGo3In”, eu até comentei alguns trechos dos codigos que eu entendi, mas o que tá complicado é entender o que exatamente faz o método join chamado no método go1 e go3, me confirma se eu estiver certo o join() aguarda a Thread anterior finalizar
antes de prosseguir com a Thread que está executando como no caso estou chamando pela thread main(), finaliza a aplicação antes das outras threads conseguir finalizar
os trechos após o 02 métodos join dos métodos go1 e go3???


public class Exemplo_Thread implements Runnable {
	
static volatile int x= 0; // (volatile) indica que uma variável pode ser alterada durante o uso de threads 

@Override // metodo sobrescrito da interface Runnable
public void run() {
	
	try{
		
		switch(x)
		{
		// Acesso ok ao método go1 sem criar uma instância pois não estou em um método estatico
		case 0: go1();
		// Não chama já que o método go2 é estático e não acessa através da instancia da classe
		case 1: new Exemplo_Thread().go2();
		// Executa normalmente pois go3 não é estático foi criado uma instância anonima desnecessáriamente, 
		//mas válido
		case 2: new Exemplo_Thread().go3();
		}		
		
	}catch(Exception e){
		
	}
	
}	
	// Método Go1 estatico e synchronized, significa que só pode ser acesso por Threads sincronizadamente.
	public static synchronized void go1()throws Exception
	{
		//imprime "GoIn" na primeira thread criada
		System.out.print("GoIn");
		/*
		  ?		
		*/		
		Thread.currentThread().join();	
		// nunca é exibido
		System.out.print("GoOut");
	}
	// Método Go2 estatico e synchronized, significa que só pode ser acesso por Threads sincronizadamente.
	public static synchronized void go2()throws Exception
	{
		System.out.print("Go2In");
		Thread.currentThread().join();
		System.out.print("Go2Out");
	}
	// Método Go3 synchronized, significa que só pode ser acesso por Threads sincronizadamente.
	public synchronized void go3()throws Exception
	{
		System.out.print("Go3In");
		Thread.currentThread().join();
		System.out.print("Go3Out");
	}
	
	public static void main(String[] args) throws Exception {
		/*
		Aqui cria as  instâncias anônimas da classe Thread e passa a classe que implementa
		Runnable como argumento, em seguida chama o método start() para tornar a Thread 
		criada em processo de execução acessando o método run() sobrescrito			
		*/
		new Thread(new Exemplo_Thread()).start();
		// Aguarda 1 segundo da thread que está rodando agora
		Thread.sleep(1000);		
		x = 1; new Thread(new Exemplo_Thread()).start();
		// Aguarda 1 segundo da thread que está rodando agora
		Thread.sleep(1000);		
		x=2; new Thread(new Exemplo_Thread()).start();
	}
	
	
}

Esse comando não faz o menor sentido. O join() faz com que a thread A espere que a thread que recebeu o join B, complete.

Chamar join() na current thread faz com que A espere A terminar, o que, se for possível, irá travar a thread.

Ok deixa eu tentar interpretar o que voce disse aplicado a este código, é irrelevante o uso de: Thread.currentThread().join(); pois ela faz um join() com a própria Thread
criada e aguarda ela mesmo finalizar?? o que pode gerar um problema na execução da thread?? mas como aplicar de forma mais eficiênte o uso do join(), para que eu
possa entender melhor o sua função.

“O join() faz com que a thread A espere que a thread que recebeu o join B, complete.”

dá para exemplificar esta teoria por favor?

Primeiro, vamos criar uma classe simples, que imprime na tela.

public class Impressora { public void imprimir() { try { for (int i = 0; i < 120; i++) { System.out.println("Imprimindo..."); Thread.sleep(500) } System.out.println("Impressão finalizada."); } catch (InterruptedException e) { System.out.println("Impressão interrompida"); } } }

Depois, vamos criar a classe que dispara essa impressão numa segunda thread, e mostra o join:

[code]public class Exemplo {
public static void main(String args[]) throws Exception {
//1. Disparamos a impressora numa thread secundária
Thread impressoraThread = new Thread(new Runnable() {
@Override
public void run() {
new Impressora().imprimir();
}
});
impressoraThread.start();

   //Note que a thread já está rodando, podemos até rodar algumas coisas em paralelo.
    for (int i = 0; i < 5; i++) {
        System.out.println("Processamento em paralelo. Feito pela main thread.");
        Thread.sleep(1000);
    }
    
    //Agora, podemos querer esperar a impressora terminar seu trabalho, antes de continuarmos
    impressoraThread.join(); //A thread que roda o main (A), irá esperar a thread da impressora (B) terminar
    System.out.println("Processamento após a impressora");
}

}[/code]

Perfeito Vini agora entendi. Obrigado!