Metoda sleep i obiekt Timer

0

Witam

Chciałbym się spytać jak uśpić poniższy wątek poprawnie. Jak mam napisane poniżej zostaje uśpiony wątek awt. Mam do napisania program emulujący kupujących w supermarkecie. Wątkami są kasy oraz klienci. Wątek klienta wywołuje waitServing() a reszta czeka. Kwestia w tym że co pewien czas powinna następować zmiana kasjera, opróżnienie kasy oraz przerwa kasjera. Dla każdej czynności wątek powinien być zatrzymany i po pewnym czasie wznowiony. Mógłby ktoś pomóc lub polecić jakiego mechanizmu zamiast tego użyć by miało sens i działało?(aktywne czekanie odpada ze względu wymogów zadania)

Dzięki

package base;

import javax.swing.Timer;

import java.awt.event.*;

public final class Register implements Runnable, Comparable<Register>
{
	public Register(int clearTimeSec, int breakTimeSec, int changeTimeSec)
	{
		clearRegisterTimer = new Timer(clearTimeSec * 1000, new ClearRegisterAction());
		
		cashierBreakTimer = new Timer(breakTimeSec * 1000, new CashierBreakAction());
		
		cashierChangeTimer = new Timer(changeTimeSec * 1000, new CashierChangeAction());
	}

	@Override
	public void run()
	{
		System.out.println(Thread.currentThread().getName() + "run");
		
		startTimers();
	}
	
	public int compareTo(Register other)
	{
		if(numberOfClients < other.numberOfClients) return -1;
		
		if(numberOfClients > other.numberOfClients) return 1;
		
		return 0;
	}
	
	public static int getTotalIncome()
	{
		return totalIncome;
	}
	
	public int getBalance()
	{
		return balance;
	}

	public String getAction()
	{
		return action;
	}

	public int getNumberOfClients()
	{
		return numberOfClients;
	}

	public void addClient()
	{
		this.numberOfClients++;
	}
	
	public synchronized void waitServing()
	{
		servingClient();
	}
	
	
	private class ClearRegisterAction implements ActionListener
	{
		public void actionPerformed(ActionEvent event)
		{		
			clearRegister();
		}
	}
	
	private class CashierBreakAction implements ActionListener
	{
		public void actionPerformed(ActionEvent event)
		{	
			takeBreak();
		}
	}
	
	private class CashierChangeAction implements ActionListener
	{
		public void actionPerformed(ActionEvent event)
		{
			changeCashiers();
			
		}
	}
	
	private void servingClient()
	{
		action = "Serving client...";
		
		balance += 100;
		
		stopTimers();

		try
		{
			Thread.sleep(5000);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			numberOfClients--;
			
			startTimers();
		}
	}
	
	private void clearRegister()
	{
		action = "Clearing the register...";
		
		stopTimers();
		
		balance = 0;
		
		try
		{
			Thread.sleep(2000);		
			
			totalIncome += balance;
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			startTimers();
		}
	}
	
	private void takeBreak()
	{
		action = "Taking a break...";
		
		stopTimers();
		
		try
		{
			Thread.sleep(4000);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			startTimers();
		}
	}
	
	private void changeCashiers()
	{
		action = "Changing cashiers...";

		stopTimers();
		
		try
		{
			Thread.sleep(5000);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			startTimers();
		}
	}
	
	private void stopTimers()
	{
		clearRegisterTimer.stop();
		
		cashierBreakTimer.stop();
		
		cashierChangeTimer.stop();
	}
	
	private void startTimers()
	{
		clearRegisterTimer.start();
		
		cashierBreakTimer.start();
		
		cashierChangeTimer.start();
	}
	
	
	private static volatile int totalIncome = 0;

	private volatile int balance = 0;
	
	private String action = "NOT SET";
	
	private volatile int numberOfClients = 0;
	
	private Timer clearRegisterTimer;
	
	private Timer cashierBreakTimer;
	
	private Timer cashierChangeTimer;
}




package base;

import static java.util.Collections.min;

import java.util.*;

public final class Client implements Runnable
{
	
	public Client(List<Register> registers)
	{
		refRegister = registers.get(0);
		
		refRegister = min(registers);
		
		System.out.println(refRegister.toString());
	}

	@Override
	public void run()
	{
		System.out.println("1");
		
		refRegister.addClient();
		
		refRegister.waitServing();
		
		System.out.println("2");
	}
	
	private Register refRegister;

}

 
0

tylko jedna konkretna odpowiedz

Object#wait(); --wstrzymuje wątek do czasu wywołania notify/notifyAll na obiekcie
Object#notify(); 
Object#notifyAll();

wszystko musi być w synchrnizujących blokach i bedziesz mógł sobie wstrzymywać kiedy chcesz wątki i wybudzać kiedy chcesz.
Żeby było jasne, wątek wstrzymuje sam siebie, a wybudza go inny wątek. No i oczywiście synchronizować i wywoływać te metody musisz na jakimś (tym tym samy dla pary wywołań wait/notifY),a tym obiektem moze być cokolwiek. Obecny wątek a może jakiś durny public Object lock=new Object();
Tutoriala znajdziesz na stronie oracla - concurency

1 użytkowników online, w tym zalogowanych: 0, gości: 1