Threadprogrammierung - zwei Threads parallel - einer beendet

Status
Nicht offen für weitere Antworten.

Proggy

Bekanntes Mitglied
Hallo,

habe ein Problem mit Threads. Etwas kompliziert zu erklären, ich versuchs mal erst allgemein.

Es werden mehrere Bildchen dargestellt. Wird auf eines geklickt, so soll das Programm fortgesetzt werden. Dies funktioniert.
Jetzt soll es aber so sein, daß, wenn niemand klickt, es nach spätestens z.B 10 Sekunden ebenfalls fortgesetzt wird. Also müßte ich doch einen zusätzlichen Thread starten, der quasi 10 Sekunden wartet und danach den Thread 1 informiert, daß es weitergeht.

Ich poste hier mal Quellcode. Zuerst mal den Hauptteil meines Programms
Code:
public void zahlenspiel()
	{
	  //addWindowListener(new WindowClosingAdapter(true));	
	}
	
	String commandstring;
	public void ablauf()
	{
		abwarter wrt1= new abwarter();    <------Deklaration einer Instanz von Klasse abwarter
		MyMouseListener w1 = new MyMouseListener();
		int rwert;
		addKeyListener(new MyKeyListener());
		addMouseListener(new MyMouseListener());
		
	        synchronized (th1) {
		while(spielnr<=5){ //Anzahl der Spiele
		while (i<=75)  //Bildwechseldauer
		   {
		    sperre=1;
			zufallszahl();
		    repaint();
		    try {
			th1.sleep(25);
		    }catch (InterruptedException exc){
		    	//nix
		    							   }                                
		   i++;
		   } //inneres while-Ende
		//zufallszahl();  //lese Werte aus Datenbank
		//repaint();
		repaint();
		sperre=0;
		jetzt_klicken=1;
		//Freigabe-Sound abspielen
		try{
		playsamplefile("klickfreigabe.wav",0,0);}catch(Exception e){//nothing
		                                                             
		}
		//repaint();
	
	repaint();
		
	   i=0; 
          
           wrt1.run();	       <----------hier starte ich doch den Thread von wrt1, oder???  <--hier liegt mein Problem
	  !!! sobald diese Zeile, also wrt1.run() nicht auskommentiert ist, klappts nicht !!!
           try {th1.wait();}catch (InterruptedException e){}    <---- funktioniert, bei Mausklick setzt Funktion
                                                                                          // MousePressed th1.notify() und Prog läuft weiter
           
	   spielnr++;
	  t_klicken=0;		//Klicksperre aktivieren
		}  
		}
		 
	
		try{
		stmt = cn.createStatement();
		//$sqlstring="INSERT INTO spielwillige (nick) VALUES ('$spielername')";
		String spieler="\"Pucki\"";
		commandstring="INSERT INTO highscores  (nick, score) VALUES (" +  spieler + " , " + punktestand +")";  
		rwert=stmt.executeUpdate(commandstring);
		   }
		//rs=stmt.executeQuery("Select nickname,punktestand from aktivespieler");}
	catch(Exception e){e.printStackTrace();} 	
		
		
		
		
		
//	nach letzter Spielrunde: Pause und Ende des Spiels
		try{  
		 repaint();
			Thread.sleep(50000);
	 }catch (InterruptedException exc){
	    	 exc.printStackTrace();
		     //nix
	    							   }  
	System.exit(0); 
	
		    
	
   }

Das Problem ist die Klasse abwarter:
Code:
public class abwarter extends Thread implements Runnable  //warte einige Zeit
{
	abwarter thread;
	hz1=0;   //Schleifenvariable
	public void start()
	{
	  if (thread==null){
	  Thread thread = new Thread(this);
	  thread.start();  
	                          }
	
	}

	  public void run()
	  {
		
		synchronized(th1){
		 for (hz1=10;hz1>0;hz1--)   //warte 10 Sekunden
		    {
			 try{thread.sleep(1000);}catch(InterruptedException ex){}
			 
		    }
         th1.notify();   //informiere th1, daß Wartezeit beendet
		                 }
		}





}  //ende Klasse abwarter

Wie kann ich das Problem lösen? Also so wartet er zwar, aber reagiert nicht auf Klicks auf die Bilder, denn dann soll er ja weiterlaufen. Mein Thread von wrt1 schiebt sich also vor th1 statt daß er parallel dazu läuft.
[/b]
 
Ein Thread startet man mit "start", nicht mit "run". Ich hab nicht ganz durchschaut wie all deine Threads miteinander interagieren, aber mir kommt es vor, als würdest du das komplizierter machen, als es notwendig wäre.

Ein Beispiel wie es ziemlich einfach geht:
Code:
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;

import javax.swing.JButton;
import javax.swing.JFrame;

public class ClickOrRun extends JFrame{
	public static void main( String[] args ){
		ClickOrRun c = new ClickOrRun();
		c.setDefaultCloseOperation(  JFrame.EXIT_ON_CLOSE );
		c.pack();
		c.setVisible( true );
	}
	
	private JButton button;
	private Wait wait;
	
	private int count = 0;
	
	public ClickOrRun(){
		wait = new Wait();
		button = new JButton( "Klick mich um zu starten" );
		button.addActionListener( new ActionListener(){
			public void actionPerformed( ActionEvent e ){
				click();
			}
		});
		
		add( button );
		wait.start();
	}
	
	public void click(){
		button.setText( "Klick mich: " + count++ );
		
		// Den Zaehler neu starten
		wait.restart();
	}
	
	private class Wait extends Thread{
		// true wenn neu gestartet wird
		private boolean restart = false;
		
		// true wenn dieser Thread gerade "click" aufruft
		private boolean onClick = false;
		
		@Override
		public void run(){
			while( true ){
				// 10 Sekunden warten
				try {
					System.out.println( 10 );
					for( int i = 9; i >= 0; i-- ){
						Thread.sleep( 1000 );
						System.out.println( i );
					}
				} catch( InterruptedException e ) {
					// ignore
				}
				
				// Falls kein Neustart: klicken
				if( !restart ){
					try {
						EventQueue.invokeAndWait( new Runnable(){
							public void run(){
								onClick = true;
								click();
								onClick = false;
							}
						});
					} catch( InterruptedException e ) {
						e.printStackTrace();
					} catch( InvocationTargetException e ) {
						e.printStackTrace();
					}					
				}
				
				restart = false;
				interrupted();
			}
		}
		
		public void restart(){
			synchronized( this ){
				restart = true;
				if( !onClick )
					interrupt();
			}
		}
	}
}
 
Hallo,

erstmal Danke.
Aber kann ich diese Lösung auch für mein Problem verwenden, schließlich sollen bei mir doch Bilder angeklickt werden und keine Buttons. Oder ist das darauf irgendwie übertragbar?

Also es ist so:
Reihenfolge:
Zuerst erscheinen die Bilder.
Dann hat der Spieler 10 Sekunden Zeit, ein Bild anzuklicken. Tut er dies, erscheinen die nächsten 5 Bilder sofort. Tut er dies nicht, so gehts nach Ablauf der 10 Sekunden automatisch weiter.
Das Ganze wird dadurch verschärft, daß ein "Countdown-Zähler" während der 10 Sekunden rückwärts läuft, der später zusätzlich noch mit einem Sound begleitet werden soll.


Ich weiss, ich muss noch viel in Java lernen.
 
Wenn du javax.swing.Timer benutzt, sparst du dir die Programmierung eines eigenen Timerthreads UND wirst keinerlei Probleme mit der Aktualisierung der GUI bekommen - Swing ist ja schließlich nicht threadsicher.

Zu Benis Lösung: Leg die Bilder doch einfach auf die Buttons...

mpG
Tobias
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben