Tag: Java
Socket Beispiele -> java.util.String split?
by admin on Apr.18, 2009, under Tutorials
Dank des schönen Wetters gibs erst nach längerer Zeit mal wieder einen Blog-Eintrag. Warum wird bei Java Socket Beispielen im Internet, immer alles mögliche in einen String gepackt (z.b. Datum, Namen usw). Dazwischen hat man dann immer diese schönen Trennzeichen wo dann immer gesplittet wird. Kaum eines der Beispiele zeigt, das Sockets auch noch andere Objekte verschicken können außer String
. Da es in Java leider nicht möglich ist, auf die Methoden einer Klasse zu zugreifen, ohne Cast, wenn diese in eine java.lang.Object initialisiert wurde (möglich, aber das entspricht nicht wirklich der Objektorientierung), muss die Klasse sowohl beim Sender als auch beim Empfänger verfügbar sein. Das Down-Casten vom java.lang.Object zu einer Klasse ist nur möglich wenn sich die Klasse sich in der Laufzeit befindet bzw. eingebunden wird. Hier mal ein Beispiel für den Client:
Socket socket = new Socket(host, port);
ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
String hallo = “Hallo”;
outputStream.writeObject(hallo);
MeineKlasse klasse = new MeineKlasse();
outputStream.writeObject(klasse);
outputStream.writeObject(new Date());
outputStream.flush();
outputStream.close();
Der Server dazu sieht zum Beispiel so aus:
ServerSocket server = new ServerSocket(port);
Socket socket = server.accept();
ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
String hallo = (String) inputStream.readObject();
MeineKlasse klasse = (MeineKlasse) inputStream.readObject();
Date date = (Date) inputStream.readObject();
inputStream.close();
Das Casten der Objekte muss in der Reihenfolge passieren in welcher diese abgeschickt wurden.
Java, Multithreading and Syncronisation
by admin on Mrz.22, 2009, under Software
Es kursieren Gerüchte, Java sei nicht richtig Mulitcore-fähig.Dies ist jedoch seit Java 1.5 grundlegend widerlegt. Jedenfalls haben wir ein bisschen herumprobiert und festgestellt, dass die Thread Technik und das Memory Model ziemlich ausgereift sind.
Allerdings ist das ganze Thema nicht ganz einfach, da man wesentlich mehr Aspekte beachten muss als bei der sequentiellen Programmierung.

Threads sind dazu da, dass Aufgaben parallel abgearbeitet werden können und somit die JVM nicht durch einen Task, der gerade ausgeführt wird, blockiert ist. Man will also erreichen, dass ein Thread über seine Laufzeit maximal ausgelastet ist.
Was ist nun aber wenn ein Thread auf das Ergebniss eines anderen Threads warten muss?
Dann sinkt die ‘Thread-Auslastung’ während der Wartezeit quasi auf null.
Hiermit sind wir schon bei dem zentralen Problem des Parallelprocessing, nämlich der Synchronisation zwischen Threads.
Wenn man von dem idealen Parallelprocessing ausgeht, dürfte keine Synchronisation zwischen den Threads vorhanden sein, weil diese kostet immer Zeit, und damit auch Performance. Da aber bei vielen MultiThread Programmen ein Mindestmaß an Synchronisation vorhanden sein sollte, ist das Java Memory Model von Nöten. (Falls man wirklich keine Synchronisation haben möchte, gibt es z.b. java.util.concurrent.atomic). Hier sind ein paar Stichworte zum Java Memory Model. Folgendes ist zu beachten:
Sichtbarkeit, Final und static Fields, die Sicherheit während der Initialisierung, was darf wer und wann, usw….
Das oben gezeigte Schema illustriert ein Modell, bei welchem das locale Thread Ergebnis, sofort wenn es fest steht, einen Push auf das Globale Object ausführt.
Dabei ist es von Bedeutung, dass während der Zeit, in der das Object bearbeitet wird, kein anderer Thread etwas an dem Object verändert bzw. schon das neue Object bekommt, d.h. das Object muss blockiert werden und die anderen Threads müssen warten.
Ab Java 1.5 gibt es hierfür unter anderem volatile und syncronise
public class Kunden{
public static volatile ArrayList list;
public Kunden(){
list = new ArrayList();
}
public syncronised void addKunde(Kunde kunde){
list.add(kunde);
}
public syncronised void removeKunde(Kunde kunde){
list.remove(kunde);
}
public syncronised Kunde getLatest(){
list.get(list.size()-1);
}
}
In diesem Beispiel gibt die Methode getLatest() immer den wirklich letzten Kunde zurück, auch wenn gerade ein neuer Kunde hinzugefügt wurde. Denn syncronised blockiert das Object, solange die Methoden add/removeKunde/getLatest damit arbeiten und führt einen Flush auf alle Objecte aus damit diese tatsächlich den aktuellen Stand im Speicher haben, wenn die Methode ausgeführt ist.
Da die Softwareunterstützung für Multicore Prozessorarchitektur immernoch nicht richtig in Fahrt ist, bzw. erst langsam im kommen ist, wird sich jeder Programmierer irgendwann einmal damit beschäftigen müssen. Jedenfalls ist dieses Thema sehr spannend, da es teilweise sehr komplex ist und man dadurch vor ganz neue Herrausforderungen gestellt wird.