Probleme mit synconisierten Threads

MonsyX

Grünschnabel
Hallo liebe Gemeine.

Ich hab ein mittelschweres für mich nicht nachvollziehbares Problem mit Java Threads, und zwar handelt es sich um 3 Threads, das erste ist zeitlich gesteuert, funktioniert auch wunderbar. Und dann kommen meine Problemkinder ins Spiel. Undzwar sind es 2 Threads der selben Klasse, aber unterschiedlichen Objectes, die sich abwechselnd ans arbeiten machen, bis der eine dem anderen das Signal gibt, das der der andere nun an der Reihe ist.
Mein Problem besteht nun darin das letzte beschriebene mal funktioniert und mal nicht, und ich weiss wirklich nichtmehr woran das liegen kann. Wenn mir jemand von euch einen Hinweis geben könnte wäre ich euch sehr dankbar.

Das hier wäre die Problemklasse, wo es zu diesen beschrieben Effekten kommt
Code:
import java.util.Random;
import java.util.concurrent.locks.*;  
public class PingPong extends Thread
{
	private String name;
	private PingPongType type;
	protected Lock lock;
	protected Condition ConditionPing;
	protected Condition ConditionPong;
	private int randomTime;
	Random num = new Random();
	
	public PingPong()
	{
		setType(PingPongType.ping);
	}
	
	public PingPong(PingPongType type, Lock lock, Condition ConditionPing, Condition ConditionPong)
	{
		setType(type);
		this.name = new String();;
		this.lock = lock;
		this.ConditionPing = ConditionPing;
		this.ConditionPong = ConditionPong;
		
	}	
	
	public void setType(PingPongType type)
	{
		switch ( type ) { 
		case ping: 
			this.type = type;
			//this.name = "Ping";
		break; 
		case pong: 
			this.type = type;
			//this.name = "Pong";
		break; 
		}
	}
	
	public void run() 
	{ 
		try
		{
		if(type == PingPongType.ping)
			runPing(); 
		else
			runPong();
		}
		catch(InterruptedException e) 
		{
			System.out.println("Thread " + type + "was interrupted:" + e);
			lock.unlock(); 
		}
	} 
	
	public void runPing() throws InterruptedException
	{
	    lock.lock(); 
	    while ( true ) 
	    {
	    	randomTime = num.nextInt(9)+1;
	    	reset();
	    	for(int i=1;i<randomTime;i++)
	    	{	
	    		sleep( 1000 );
	    		if(i % 2 == 0)
	    		{
	    			addTime();
	    		}
	    	}
	    	ConditionPong.signal(); // <=== hier scheint das problem zu liegen
	    	ConditionPing.await();
	    	reset();
	    }
	}
	
	public void runPong() throws InterruptedException
	{
	    lock.lock(); 
	    ConditionPong.await(); //<==== der scheint das signal nicht aufzufangen
	    while ( true ) 
	    {
	    	randomTime = num.nextInt(9)+1;
	    	reset();
	    	for(int i=1;i<randomTime;i++)
	    	{	
	    		sleep( 1000 );
	    		if(i % 2 == 0)
	    		{
	    			addTime();
	    		}
	    	}
	    	ConditionPing.signal();
	    	ConditionPong.await();
	    }
	}
	
	public void addTime()
	{
		String temp = new String();
		int i;
		switch ( this.type ) { 
			case ping:
				temp = "Pi";
				for(i=3;i<=this.name.length()-1;i++)
					temp += "i";
				temp += "ng";
			break; 
			case pong: 
				temp = "Po";
				for(i=3;i<=this.name.length()-1;i++)
					temp += "o";
				temp += "ng";
			break; 
		}
		this.name = temp;
	}
	
	public String toString()
	{
		return this.name;
	}
	
	public void reset()
	{
		switch ( this.type ) { 
		case ping:
			this.name = "Ping";
		break; 
		case pong: 
			this.name = "Pong";
		break; 
	}
	}
}

Code:
public enum PingPongType {
	ping, pong
}

Code:
import java.util.*;

public class TimerControledTask implements Runnable
{
	private long start;
	private PingPong Ping;
	private PingPong Pong;
	private Thread ThreadPing;
	private Thread ThreadPong;
	
	
	public TimerControledTask(PingPong Ping, Thread ThreadPing, PingPong Pong, Thread ThreadPong)
	{
		this.Ping = Ping;
		this.Pong = Pong;
		this.ThreadPing = ThreadPing;
		this.ThreadPong = ThreadPong;
		Date temp = new java.util.Date();
		start = temp.getTime();	
	}
	
	public void run() 
	{ 
		
		try { 
			Thread.sleep(100); 
			this.start += 100;
			for(int i=0;i<30;i++)
			{
				if(ThreadPing.getState() != java.lang.Thread.State.WAITING)
				{
					System.out.println(Ping.toString() + "             " + (new java.util.Date().getTime() - start)/1000.0);
				}
				if(ThreadPong.getState() != java.lang.Thread.State.WAITING)
				{
					System.out.println((new java.util.Date().getTime() - start)/1000.0 + "             " + Pong.toString());
				}
				Thread.sleep((i+1)*500-(new java.util.Date().getTime() - start)); 
			}
			ThreadPing.interrupt();
			ThreadPong.interrupt();
		} 
		catch (InterruptedException e){}
	} 
}

Code:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


public class testPingPong {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		PingPong Ping;
		PingPong Pong;
		final Lock lock                = new ReentrantLock(); 
	    final Condition ConditionPing  = lock.newCondition(); 
	    final Condition ConditionPong  = lock.newCondition(); 

		Thread ThreadPing = new Thread(Ping = new PingPong(PingPongType.ping, lock, ConditionPing, ConditionPong));
		Thread ThreadPong = new Thread(Pong = new PingPong(PingPongType.pong, lock, ConditionPing, ConditionPong));
		Thread ThreadTime = new Thread(new TimerControledTask(Ping, ThreadPing, Pong, ThreadPong));
		
		ThreadTime.start(); 
		ThreadPing.start();
		ThreadPong.start();
	}
}
 
Zurück