Ho modificato un po' il metodo run() ma ora ho difficoltà con la gestione di wait() e notify().
L'aspetto teorico dei thread mi è chiaro ma non riesco a capire perchè il metodo notify() nel mio caso non riesce a sbloccare il thread AttivitaPrincipale e continuare l'esecuzione del suo metodo run().
Questa è la classe AttivitaPrincipale:
public class AttivitaPrincipale implements Runnable {
  
  private boolean eseguita = false;
  private Scontrino scontrinoCorrente = null;
  private RecordTipoAcquisti tipoAcquisti = null;
  private RecordScontrino recordScontrino = null;
  public synchronized void run() {
    if (eseguita)
      return;
    eseguita = true;
    
    // Chiedi tipo souvenir
    tipoAcquisti = AttivitaIO.chiediTipoSouvenir();
    CreaNuovoScontrino creaScontrino = new CreaNuovoScontrino();
    Executor.perform(creaScontrino);
    scontrinoCorrente = creaScontrino.getRisultato();
    Thread sottoRamoMagneti = null;
    Thread sottoRamoBerretti = null;
    if (tipoAcquisti.isMagneti()) {
      // si' magneti
      sottoRamoMagneti = new Thread(new AttivitaSottoramoMagneti(scontrinoCorrente));
      sottoRamoMagneti.start();
      try {
    	  while(eseguita) {
    	  			this.wait();
    	  			eseguita = false;
    	  }
      } catch (InterruptedException e) {
		e.printStackTrace();
      }
    }
    ...
    
    }
}
in questa classe ho usato il flag "eseguita" per gestire tramite un ciclo while il wait (come mi hai suggerito prima). Effettivamente funziona tutto perfettamente qui e l'esecuzione al thread "AttivitaSottoramoMagneti".
Questa è la classe AttivitaSottoramoMagneti:
public class AttivitaSottoramoMagneti implements Runnable {
  
  private boolean eseguita = false;
  private Scontrino scontrinoCorrente = null;
  private boolean ancoraMagneti = true;
  private Set<String> magnetiLetti;
  private RecordAcquisto magneteSelezionato;
  public AttivitaSottoramoMagneti(Scontrino scontrinoCorrente) {
    this.scontrinoCorrente = scontrinoCorrente;
  }
  public synchronized void run() {
    if (eseguita)
      return;
    eseguita = true;
    while (ancoraMagneti) {
        LeggiMagneti object = new LeggiMagneti();
    	Executor.perform(object);
    	Set<String> result = object.getRisultato();
        RecordAcquisto magnete = AttivitaIO.mostraSouvenirPerSelezione(result);
        AggiornaScontrino aggiorna = new AggiornaScontrino(magnete, scontrinoCorrente);
        if(AttivitaIO.altroMagnete() == false) {
      	  	ancoraMagneti = false;
      	  	notifyAll();
      	}
    }
  }
}
Ho utilizzato notifyAll() per essere sicuro di sbloccare il thread bloccato (che sarebbe AttivitaPrincipale). L'esecuzione procede senza problemi fino al settaggi del flag "ancoraMagneti" a false poi però non avviene lo sblocco del thread "AttivitaPrincipale".
Dove sbaglio?
Ho cercato di capire attraverso gli esempi trovati in rete ma l'utilizzo di wait() e notify() mi sembra fatto esattamente come lo faccio io solo che negli esempi funziona mentre a me no.