PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Java: Threads, Millisekunden...



Felix Z.
18-12-2003, 20:41
Hallo an alle,

Ich versuche mich an einer einfachen Karte zur Standortanzeige.
Das ganze soll am Ende einfach ein kleines Programm sein, dass auf einer Karte einen bestimmten Standort anzeigt, der ihm vorher als Parameter übergeben wurde. Eine ganz simple Übung also.

Dieser Punkt soll blinken - ich habe das so realisiert, dass von den Farbanteilen je Threaddurchlauf 5 abgezogen/addiert werden (RGB).

Hier ist mein bisheriger Code:



import javax.swing.*;
import java.awt.*;


public class Map
extends JFrame
{

int par0 = 0;
int par1 = 0;
int rc = 255;
int gc = 255;
int bc = 255;

public Map()
{
}

public Map(String par0, String par1)
{

setSize(640,480);
setBackground(Color.white);
this.par0 = Integer.parseInt(par0);
this.par1 = Integer.parseInt(par1);
setTitle("Standpunkt von:");
}


public void paint(Graphics g)
{
g.setColor(new Color(rc,gc,bc));
g.drawOval(par0,par1,10,10);
g.fillOval(par0,par1,10,10);
}

public static void main(String args[])
{
if(args.length < 1)
{
System.out.println("Programmaufruf benötigt 2 Argumente");
System.exit(0);
}
String par0 = "";
String par1 = "";

par0 = args[0].toString();
par1 = args[1].toString();

Map bk = new Map(par0,par1);
bk.show();
Thread mainThread = new Thread(bk.new mainThread());
mainThread.start();

}


class mainThread implements Runnable
{
int Richtung = 0;

public void run()
{
while(true)
{
if(Richtung == 0)
{
gc -= 5;
bc -= 5;
if(gc == 0 && bc == 0)
{
Richtung = 1;
}
}
else
{
gc += 5;
bc += 5;
if(gc == 255 && bc == 255)
{
Richtung = 0;
}
}


repaint();
try
{
Thread.sleep(1);
}
catch(InterruptedException ie)
{
break;
}
}


}
}
}


Soweit so gut.
Eigentlich funktioniert das ohne Probleme, doch als ich das Programm unter Windows getestet habe, stellte ich fest, dass die Intervalle des ein- und ausblendens viel höher sind als unter Linux.

Wie kann ich mir das erklären?
Behandelt Windows Threads anders als Linux?

peschmae
19-12-2003, 07:42
ja, schon ein bisschen - unter Linux sind Threads n bisschen abgespeckte Prozesse - unter Windows glaubich etwas spezielles, weil unter Win der Prozesswechsel recht lahm ist.

Allerdings musst du dich wohl damit abfinden - schliesslich sind ja auch alle PCs verschieden schnell, etc. - du kannst nicht erwarten dass das jeweils gleich schnell abläuft.

Allerdings weiss ich nicht, wie die Java-Threads implementiert sind. Evtl gibts mit der IBM-JRE für Linux bessere Ergebnisse.

MfG Peschmä

comrad
19-12-2003, 10:06
ich würd eher nach zwei anderen Methoden es versuchen:

a) den Thread einfach für die bestimmte Zeit schlafen legen
b) die Zeit selbst berechnen anhand von Millisekunden


Lösung a)



public void run()
{
final int SCHLAFZEIT = 1000; // Millisekunden
while(true)
{
/*
* Hier den Code für das Punktmalen
*/
this.sleep(SCHLAFZEIT);
}
}



Lösung b)


public void run()
{
final int SCHLAFZEIT = 1000; // Millisekunden
long currentTime;
long latestTime = System.currentTimeMillis();

while (true)
{
currentTime = System.currentTimeMillis();
if ((currentTime - latestTime) > SCHLAFZEIT)
{
latestTime = System.currentTimeMillis();
/*
* Hier deinen code für das Punktmalen
*/
}
}
}


Hoffe, dass dir das hilft.
comrad

anda_skoa
19-12-2003, 11:26
Eine Millisekunde zu schlafen, wie das im Code von Felix gemacht wird, ist ohnehin nicht wirklich machbar.

Eher in Vielfachen von 10 Millisekunden, darunter ist zuviel Einfluss von anderen Prozessen, etc.

Für Blinken reicht womöglich noch viel ein größere Updateintervall.

Ciao,
_

Felix Z.
19-12-2003, 11:54
Danke für die Antworten!

Die Lösung b) scheint mir eine elegante zu sein, damit erziele ich auf beiden Systemen sehr sehr ähnliche Ergebnisse.

peschmae
19-12-2003, 18:33
Lösung b frisst aber Prozessorzeit. Das find ich blöd.

sleep() hingegen legt den Prozess schlafen - er braucht dann keine Prozessorzeit mehr.

Ich hielte da mehr von einem "adaptiven" System, das zuerst mal sleep(10) macht (für 10 ms) und dann schaut, wie lange das dauerte und dementsprechend bei den ersten paar Durchläufen die Zeit ungefähr anpasst so dass es dann stimmt.

MfG Peschmä

anda_skoa
20-12-2003, 10:09
Original geschrieben von peschmae
Lösung b frisst aber Prozessorzeit. Das find ich blöd.

sleep() hingegen legt den Prozess schlafen - er braucht dann keine Prozessorzeit mehr.


Lässt sich ja kombinieren.
Wenn die Bedingung des if nicht erfüllt ist, weiß man wie lange man sleep machen muss, bis sie erfüllt ist.
Geht also leicht im else Teil.

Ciao,
_

peschmae
20-12-2003, 17:53
mal wieder viel besser als meine Idee :D

MfG Peschmä

comrad
22-12-2003, 07:02
Hi ihr beiden,

also wie jetzt genau. Die Lösung klingt spannend! Leider kann ich dem nicht ganz folgen.

comrad

peschmae
22-12-2003, 08:14
er - und ich jetzt auch - meint das so:



else
this.sleep(latestTime + SCHLAFZEIT - currentTime);

(bei deiner Lösung b in der while-Schleife natürlich)

MfG Peschmä

P.S. wenn du bei ifs nacher nur eine Zeile hast, kannst du die Klammern auch weglassen - find ich nämlich übersichtlicher. Andere natürlich nicht :D

comrad
22-12-2003, 10:24
ah okay, nu is alles klar. :) danke!