Frage zu Threading



  • Hallo,
    Ich habe eine Frage bzgl. Threading. Ich habe ein kleines Programm zum Abspielen von Sound-Dateien.
    Wenn ich in der GUI auf play drücke, wird die Methode Play(PfadDesSounds); eines PlayerServices aufgerufen.
    Diese sieht in etwa so (Pseudocode) aus:

    public synchronized void Play(String Path){
    
    	// Damit die GUI nicht einfriert, wird ein neuer Thread gestartet:
    	Thread worker = new Thread(){
    
    		@Override
    		public void run() {
    
    			if(player!=null){
    				player.stop();
    			}
    			player = new Player(Path);
    
    			player.start();
    
    		}
    
    	};
    	worker.start();
    
    }
    

    Hierbei ist angemerkt dass stop() und new Player() jeweils zwischen 0.1 und 0.5 sek dauern können.

    Und dadurch ergibt sich folgendes Problem:

    User klickt in der GUI auf play.
    Thread a startet,
    Thread a prüft ob player != null, merkt es gibt noch keinen player.
    Thread a erzeugt einen neuen Player. (Dies kann nun 0.1 bis 0.5 sek dauern)
    User klickt in der GUI auf play für einen anderen oder den gleichen sound.
    Wenn nun Thread b für den zweiten sound startet:
    Thread b startet,
    Thread b prüft ob player != null, merkt player == null weil der Konstruktor im ersten Thread noch nicht fertig ist
    und noch nichts zurückgegeben hat.
    Thread b stoppt also den player nicht!!
    Thread b erzeugt ebenfalls einen neuen Player.

    Das Ergebnis sind zwei ein wenig zeitversetzte laufende sounds.

    Natürlich möchte ich nur den zuletzt ausgewählten Sound wiedergeben und den ersten abbrechen/gar nicht erst starten.
    Ich habe nun einiges versucht, allerdings noch nicht viel Erfahrung mit Threading.

    Daher würde ich mich über Lösungsvorschläge freuen!
    MfG



  • Verwende innerhalb der run methode einen lock. Der Lock sollte am besten teil der äußeren klasse sein, damit immer die selbe instanz verwendet wird.

    Alternativ könntest du auch nur einen backgroundthread starten, der per blockingqueue neue titel entgegennimmt.

    Oder du kannst die != null problematik auch durch eine AtomicReference lösen.

    Der Einfachheithalber würde ich aber zu 1. Möglichkeit raten (oder evtl. noch 2.)


Anmelden zum Antworten