webForumDet fria alternativet

Tom loop drar cpu-kraft

7 svar · 394 visningar · startad av Gein

GeinMedlem sedan sep. 20005 700 inlägg
#1

Jag har en tom loop som rullar så länge ett villkor är uppfyllt. Detta för att se till att tråden inte dör förrän det är OK. Att ha en tom loop innebär att programmet i princip hela tiden kollar om villkoret är sant och detta drar all tillgänglig CPU-kraft. För att lösa detta har jag lagt in en sleep på ett par sekunder i loopen.
Finns det ett bättre och snyggare sätt att lösa det på, där man samtidigt har direkt synkronisering? Med min lösning så kan programmet i värsta fall vänta dessa sekunder i onödan om villkoret förändras precis efter kontroll.

jmeMedlem sedan maj 20012 237 inlägg
#2
public class Test implements Runnable
{
	boolean done = false;
	
	public void run()
	{
		
		try
		{
			while(!done)
			{
				// gör vad du ska
				Thread.sleep(200);
			}
		}
		catch(InterruptedException ie)
		{
			
		}
	}
}

Om du vill stoppa körningen av tråden direkt, utan att tråden sover ( i detta fall, 200 ms) så kan du anropa Thread-klassens interrupt().

spangoMedlem sedan juni 20008 205 inlägg
#3

Java har en massa fräcka blockingfunktioner fr.o.m. version (1.)5. Blocking queues skulle kunna användas i ditt fall...


class C {

    private BlockingQueue<Object> lock = new ArrayBlockingQueue<Object>(1);

    public void run(){
        System.out.print("Börjar tråden...");
        lock.take();
        System.out.println(" avslutar.");
    }

    public void stopRunning(){ lock.add(new Object()); }

}

När run() börjar är kön tom, så take() väntar tills något hamnar i kön, vilket händer vid anrop av stopRunning(). Detta innebär förstås att tråden själv inte kan avgöra exakt när väntandet ska avbrytas, vill du decoupla det från vad det nu är som bevakas får du göra någon lyssnarvariant.

Mer om trådningshjälpmedel finns på http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/package-summary.html

GeinMedlem sedan sep. 20005 700 inlägg
#4

BlockingQueue verkar bekvämt men jag kan tyvärr inte gå över till 1.5 i detta fall.

public class ThreadStream implements Runnable {
	public Thread activity = new Thread(this);

	private VideoServer vs;
	private String cAddress;
	private String cPort;
	private String mediaLocator;

	public ThreadStream(VideoServer vs, String mediaLocator,
			String cAddress, String cPort) {
		this.vs = vs;
		this.mediaLocator = mediaLocator;
		this.cAddress = cAddress;
		this.cPort = cPort;
	}

	public void run() {

		VideoTransmit VT = new VideoTransmit(mediaLocator, cAddress, cPort);
		vs.setVT(VT);
		
		// Start the transmission
		System.out.println("Stream starting from " + mediaLocator + " to "
				+ cAddress + ":" + cPort);
		String result = VT.start();

		// result will be non-null if there was an error. The return
		// value is a String describing the possible error. Print it.
		if (result != null) {
			System.err.println("Error : " + result);
			System.exit(0);
		}
		while (vs.getStream()) {
			try {Thread.sleep(500);} catch (Exception e) {} // Continue streaming
		}

		// Stop the transmission
		VT.stop();
		vs.setVT(null);
		System.out.println("Transmission ended.");
	}
}

Så här ser trådklassen ut.
Så här skapar jag en tråd

ThreadStream t = new ThreadStream(vs, vidSource, arrInput[0], cPort);
vs.setStreaming(true);
t.activity.start();

Om jag försöker köra t.interrupt() så klagar den: "cannot resolve symbol method interrupt ()

spangoMedlem sedan juni 20008 205 inlägg
#5

interrupt() ligger i Thread, så du får köra t.activity.interrupt(). Sen använder du Thread.sleep() i stället för Thread.sleep(int).

GeinMedlem sedan sep. 20005 700 inlägg
#6

Det finns ingen Thread.sleep() (utan parameter)?

spangoMedlem sedan juni 20008 205 inlägg
#7

Just ja, det var wait() jag tänkte på. Jaja, ta nåt godtyckligt tal.

GeinMedlem sedan sep. 20005 700 inlägg
#8

Tack för hjälpen!

130 ms totalt · 3 externa anrop · v20260731065814-full.0e50b1ef
127 ms — hämta forumlista (db)
0 ms — hämta statistik (cache)
128 ms — hämta tråd, inlägg och bilagor (db)