PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Thread + InputStream = 100% CPU?



nul
03-06-2006, 13:43
Wieder mal ne Frage zum Thema Java von mir.
Dabei geht es um Threads, meinen absoluten Lieblingsthema in fast jeder Programmiersprache die ich kenne.
Und zwar benutze ich einen DataInputStream in einem Thread der wartet, bis etwas anliegt und das dann versucht zu lesen. Das ganze sieht dann so aus:

public void run() {
try {
char c;

while ( this.managedConnection.getState() == CONNECTION_STATE.CONNECTION_OPEN ) {
// System.out.println( "s: " + this.managedConnection.getState() );
InputStream inputStream = new FileInputStream( this.device );
DataInputStream dataStream = new DataInputStream( inputStream );

for ( int i = 0; i < dataStream.available(); i++ ) {
c = dataStream.readChar();

if ( c != -1 ) {
this.messageBuffer.addToMessage( c );
if ( this.messageBuffer.checkMessage() ) {
// TODO Inform about message complete
}
}
}
dataStream.close();
inputStream.close();
}
} catch ( FileNotFoundException e) {
e.printStackTrace();
} catch ( IOException e ) {
e.printStackTrace();
}
}
Nun brauch das Ding aber 100% CPU auslastung was es ja nicht sein kann.
Hat jemand einen besseren Vorschlag?

mfg nul

bischi
03-06-2006, 13:58
Vielleicht so:



readLine()
Deprecated. This method does not properly convert bytes to characters. As of JDK 1.1, the preferred way to read lines of text is via the BufferedReader.readLine() method. Programs that use the DataInputStream class to read lines can be converted to use the BufferedReader class by replacing code of the form:

DataInputStream d = new DataInputStream(in);


with:

BufferedReader d
= new BufferedReader(new InputStreamReader(in));


MfG Bischi

nul
03-06-2006, 16:27
Ich glaube du hast mich nicht richtig verstanden. Mein Problem liegt nicht darin eine Datei zu lesen. Viel mehr liegt es in der while-Schleife.
Die Schleife laeuft endlos und darin soll geprueft werden ob in der Datei etwas zu lesen ist.
Ideal waere wenn es so wie in C bei einer Fifo ist - der Thread wartet wo lange in der While-Schleife bis etwas am InputStream kommt und liest es dann, dann wiederholt er sich.
Die while-Bedingung ist praktisch immer true, der Thread laeuft also waerend der gesamten Programmzeit - und beansprucht, ob ich nun einen Buffered Reader oder nen DateInputStream verwende, immer ca. 90% CPU-Last wegen der Endlosschleife.

anda_skoa
03-06-2006, 16:37
Wenn du readChar machst, dann blockiert das auch wie in C.
Bzw was auch immer du dann wirklich zum Lesen benutzt, einzelne Zeichen ja wohl kaum :)

Ciao,
_

bischi
04-06-2006, 10:08
Ich glaube du hast mich nicht richtig verstanden. Mein Problem liegt nicht darin eine Datei zu lesen. Viel mehr liegt es in der while-Schleife.
Die Schleife laeuft endlos und darin soll geprueft werden ob in der Datei etwas zu lesen ist.
Ideal waere wenn es so wie in C bei einer Fifo ist - der Thread wartet wo lange in der While-Schleife bis etwas am InputStream kommt und liest es dann, dann wiederholt er sich.
Die while-Bedingung ist praktisch immer true, der Thread laeuft also waerend der gesamten Programmzeit - und beansprucht, ob ich nun einen Buffered Reader oder nen DateInputStream verwende, immer ca. 90% CPU-Last wegen der Endlosschleife.

afaik wird - wenn du nen BufferedReader und readline verwendest, jeweils gewartet, bis eine volle Zeile zur Verfügung steht. Diese wird eingelesen und danach wird wieder gewartet.

MfG Bischi

nul
05-06-2006, 15:52
afaik wird - wenn du nen BufferedReader und readline verwendest, jeweils gewartet, bis eine volle Zeile zur Verfügung steht. Diese wird eingelesen und danach wird wieder gewartet.

MfG Bischi
Hm, das kann ich aber ueberhaupt nicht bestaetigen.
Meine zwei letzten Versuche sind:

/*public void run() {
try {
char[] chars = new char[100];
//InputStream inputStream = new FileInputStream( this.device );
BufferedReader reader = new BufferedReader( new FileReader( this.device ) );

while ( this.managedConnection.getState() == CONNECTION_STATE.CONNECTION_OPEN ) {
//System.out.println( "Thread running!" );

if ( reader.read( chars ) != -1 ) {
this.messageBuffer.addToMessage( chars );
} else {
reader.reset();
//reader.close(); reader = null;
// reader = new BufferedReader( new FileReader( this.device ) );
}
}

} catch ( FileNotFoundException fnfe ) {
fnfe.printStackTrace();
} catch ( IOException ioe) {
ioe.printStackTrace();
}
}*/

public void run() {

try {
BufferedReader reader = new BufferedReader( new FileReader( this.device ) );

while ( this.managedConnection.getState() == CONNECTION_STATE.CONNECTION_OPEN ) {

String line = reader.readLine();

//this.messageBuffer.addToMessage( line.toCharArray() );

if ( line == null )
break;

}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println( "thread end" );
}
Erstes mit read funktioniert teilweise. Es wird solange gewarten bis was zum lesen ist, das wird dann gelesen. Dann erreicht er das Ende der Datei EOF und gibt mir immer nur -1 zurueck. Das heisst dann nachdem er das erste mal gelesen hat geht die Schleife weiter und read blockiert dann ueberhaupt nicht. Hab dann versucht den reader neu zu machen usw, hat aber nichts gebracht.
Zweites funktioniert schon ueberhaupt nicht (readLine). Ich erhalte nur null als Rueckgabewert und blockieren tut er auch nicht.

Noch jemand nen vorschlag :( bin kurz davor ein rm -rf ~/workspace auszufuehren!