Dallo stralcio di codice che hai incollato non si capisce molto perché manca la classe che contiene la actionPerformed per cui non si capisce le variabili come sono inizializzate; cmq se dici che la notify gira e l'altro thread resta in attesa è perchè stai agendo su due istanze della classe semaforo diverse.
In effetti credo che il semaforo che si mette in wait sia inizializzato nella classe Command mentre l'altro nella classe che contiene la actionPerformed.
Se vuoi che il semaforo sia unico per processo ti conviene fare un singleton ossia qlc del genere:
public class Semaforo {
private static Semaforo instance;
static {
instance = new Semaforo();
}
private Semaforo(){
...
}
public static Semaforo getSemaforo() {
return instance;
}
...
}
e dove instanzi un Semaforo anzichè fare
Semaforo s = new Semaforo();
fai
Semaforo s = Semaforo.getSemaforo();
Così sei sicuro che hai un'unica istanza del semaforo in tutto il processo.
In ogni caso mi sembra sbagliata anche la gestione dei synchronized nella classe semaforo in quanto così com'è quando il primo thread sta nella rewait, il secondo non entrerà mai nel blocco synchronized della restart; secondo me dovresti levarli entrambi.