Métodos static e não static sincronizados [RESOLVIDO]

Olá mais uma vez irmãos, estou com um problema. Estou com um programa
apenas para aprendizagem, e não consigo fazer oum bloco static sincronizado notificar o
outro método de instância sincronizado

public class Teste01 implements Runnable {
	public void restart() {
		startMe();
	}

	public void run() {
		synchronized (this) {
			System.out.println("Running");
			try {
				wait();
				System.out.println("Retornado");
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	public static void startMe() {
		Class ref = null;
		try {
			ref = Class.forName("Teste01");
		} catch (ClassNotFoundException e) {

		}
		synchronized (ref) {

			System.out.println("olá");
			ref.notify();
		}
	}

	public static void main(String[] args) {
		Teste01 t = new Teste01();
		Thread t2 = new Thread(t);

		t2.start();
		for (int i = 0; i < 10000000; i++) {//para garantir que a thread inicie primeiro

		}
		t.restart();

	}
}

Resumindo, o programa tem q exibir “Running” da thread que depois fica em estado de wait(),
depois exibe “olá” num método static e por fim ele notifica a thread de “Running” de volta que exibe por final “Retornado”.
Porém o método static não consegue notificar pq não acha o bloqueio, alguem sabe dizer pq??
muito Obrigado!

Você precisa que o wait() e o notify sejam dados sobre o mesmo objeto. No método não sincronizado, seu código está fazendo sobre this, que é uma instância de Teste01. No método sincronizado, você está fazendo sobre um objeto do tipo Class<Teste01>, cujo valor é Teste01.class.

Existem duas soluções para isso. A primeira, é passar Teste01 como parâmetro:

public static void startMe(Teste01 lock) { synchronized (lock) { System.out.println("olá"); ref.notify(); } }

E então passar this no método restart.

public void restart() { startMe(this); }

A segunda solução seria sincronizar por Teste01.class na hora do wait:

public void run() { synchronized (Teste01.class) { System.out.println("Running"); try { wait(); System.out.println("Retornado"); } catch (InterruptedException e) { e.printStackTrace(); } } }

foi oq imaginei, ViniGodoy vc é fera. Esse fórum ta de parabéns, sempre
respondem às minhas dúvidas. Muito Obrigado

É claro que a solução real é não fazer esse tipo de coisa. O melhor tipo de sincronização que tem é o da instância, preferencialmente com um objeto próprio para sincroniza-la.