# Thread erneut starten?



## JavaNooby (23. Jul 2008)

Hi, ich bin gerade dabei n Moorhuhn clone zu erstellen, es funktioniert alles bis auf eine kleinigkeit ^^.
Ich habe eifrig gegoogled und bin auf eine wunederschöne Klasse gestoßen die Nebenläufig Wav Dateien abspielt.
Beim ersten mal starten funktioniert das auch einwandfrei, nur wie kann ich den Thread erneut starten wenn ich nochmal schieße?
Hier mal die Klasse die das Wavfile abspielt:


```
package logic;
import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;
 
public class SoundPlayer extends Thread {
 
	private String filename;
 
	private Position curPosition;
 
	private final int EXTERNAL_BUFFER_SIZE = 524288; // 128Kb
 
	public boolean shoot =false;
	
	enum Position {
		LEFT, RIGHT, NORMAL
	};
 
	public SoundPlayer(String wavfile) {
		filename = wavfile;
		curPosition = Position.NORMAL;
	}
 
	public SoundPlayer(String wavfile, Position p) {
		filename = wavfile;
		curPosition = p;
	}
	@Override
	public void run() {
	
	
			
			System.out.println(shoot);
		File soundFile = new File(filename);
		if (!soundFile.exists()) {
			System.err.println("Wave file not found: " + filename);
			return;
		}
 
		AudioInputStream audioInputStream = null;
		try {
			audioInputStream = AudioSystem.getAudioInputStream(soundFile);
		} catch (UnsupportedAudioFileException e1) {
			e1.printStackTrace();
			return;
		} catch (IOException e1) {
			e1.printStackTrace();
			return;
		}
 
		AudioFormat format = audioInputStream.getFormat();
		SourceDataLine auline = null;
		DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
 
		try {
			auline = (SourceDataLine) AudioSystem.getLine(info);
			auline.open(format);
		} catch (LineUnavailableException e) {
			e.printStackTrace();
			return;
		} catch (Exception e) {
			e.printStackTrace();
			return;
		}
 
		if (auline.isControlSupported(FloatControl.Type.PAN)) {
			FloatControl pan = (FloatControl) auline
					.getControl(FloatControl.Type.PAN);
			if (curPosition == Position.RIGHT)
				pan.setValue(1.0f);
			else if (curPosition == Position.LEFT)
				pan.setValue(-1.0f);
		} 
 
		auline.start();
		int nBytesRead = 0;
		byte[] abData = new byte[EXTERNAL_BUFFER_SIZE];
 
		try {
			while (nBytesRead != -1) {
				nBytesRead = audioInputStream.read(abData, 0, abData.length);
				if (nBytesRead >= 0)
					auline.write(abData, 0, nBytesRead);
			}
		} catch (IOException e) {
			e.printStackTrace();
			return;
		} finally {
			auline.drain();
			auline.close();
		}
		this.interrupt();
		
	}
}
```

Von Außen hab ich mir ein Object der Klasse erstellt und starte diese mit .start().
Zum erneuten Starten gibt es dummerweiße keine nützliche funktion (,resume() ist deprecated ;( ).
Wenn ich direct die run() Methode aufruf hängt das spiel bis der Sound abgespielt ist ^^.
Kann mir da jemand weiterhelfen?

thx


----------



## Kim Stebel (23. Jul 2008)

du musst halt ne neue Instanz erstellen für jedes mal, dass du den sound abspielen willst. Ja, das ist bei threads so...wenn die einmal beendet sind kann man die wegschmeißen.


----------



## JavaNooby (23. Jul 2008)

Och  nö das ist ja blöd


----------



## SlaterB (23. Jul 2008)

die Alternative wäre, die run-Operation nie auslaufen zu lassen,
sondern ihn am Ende z.B. schlafen zu legen und zum nächsten Durchlauf (Schleife) wieder aufzuwecken


----------



## FArt (23. Jul 2008)

... oder ein Scheduler bzw. Executor...


----------



## Marco13 (23. Jul 2008)

Das wäre die bessere - und insbesondere sollte nicht bei jedem Abspielen die Datei neu von der Festplatte geladen werden....


----------



## JavaNooby (23. Jul 2008)

mhh,
meine erste idee war ne while(boolean) Schleife um den Thread zu legen und die boolean Variable public zumachen um von Außen dann den Thread starten bzw stoppen zu können, hat aber nicht so ganz hingehauen ^^.
Ich mach einfach immer ne neue Instanz ^^

Danke für die Antworten


----------



## Gelöschtes Mitglied 5909 (23. Jul 2008)

es steht n kleines Beispiel in der API bei ThreadPoolExecutor


```
class PausableThreadPoolExecutor extends ThreadPoolExecutor {
   private boolean isPaused;
   private ReentrantLock pauseLock = new ReentrantLock();
   private Condition unpaused = pauseLock.newCondition();

   public PausableThreadPoolExecutor(...) { super(...); }

   protected void beforeExecute(Thread t, Runnable r) {
     super.beforeExecute(t, r);
     pauseLock.lock();
     try {
       while (isPaused) unpaused.await();
     } catch (InterruptedException ie) {
       t.interrupt();
     } finally {
       pauseLock.unlock();
     }
   }

   public void pause() {
     pauseLock.lock();
     try {
       isPaused = true;
     } finally {
       pauseLock.unlock();
     }
   }

   public void resume() {
     pauseLock.lock();
     try {
       isPaused = false;
       unpaused.signalAll();
     } finally {
       pauseLock.unlock();
     }
   }
 }
```


----------

