Portal > Foren > Java > Allgemeine Java-Programmierung > Connection manager als Stack
Antwort
 
Themen-Optionen Thema durchsuchen
Alt 02.06.2004, 13:17 Nach oben    #1
LordOfCodes
Gast
 
Beiträge: n/a
Standard Connection manager als Stack

Hi leute.

Nettes Forum!! Na dann poste ich doch gerade mal eine Frage:

Ich habe eine Klasse geschrieben, wellche von aussen her gesehen wie ein Stack funktioniert (also man kann Objekte hinein "pushen" und wieder heraus "popen").
Die Objekte, welche im Stack abgelegt werden, sollen dann über das Netzwerk verschickt werden, und die Objekte, welche aus dem Netzwerk kommen, sollen dann über die Methode pop() abgeholt werden können.
Ich hoffe, ihr kapiert in etwa, was ich gemacht habe.

Nun zu meinem Problem: Ich wollte die Klasse so gut wie möglich Thread-Save machen, also dass keine Fehler auftreten bei mehrernen Threads die darauf zugreifen. Jedoch funktioniert das nicht richtig, irgend etwas erzeugt einen deat-lock..

Kann sich bitte jemand die Klasse ansehen und verbesserungsvorschläge posten?
Besten Dank schon im Voraus.

Code:
public class StackSerializer {
  
  ObjectInputStream m_ois;
  ObjectOutputStream m_oos;
  Vector m_inputStack;
  Vector m_outputStack;
  boolean m_read = true;
  boolean m_write = true;
  Thread m_inputThread;
  Thread m_outputThread;
  
  public StackSerializer(InputStream is, OutputStream os) 
  throws Exception {
    m_oos = new ObjectOutputStream(os);
    m_ois = new ObjectInputStream(is);
    m_inputStack = new Vector();
    m_outputStack = new Vector();
    m_inputThread = new Thread() {
      public void run() {
        while (m_read) {
          try {
            insert(m_ois.readObject());
            System.out.println("read object");
          } catch (Exception ex) {
            insert(ex);
            m_read = false;
          }
        }
      }
    };
    m_outputThread = new Thread() {
      public void run() {
        while (m_write) {
          try {
            m_oos.writeObject(remove());
            System.out.println("wrote object");
          } catch (Exception ex) {
            insert(ex);
            m_write = false;
          }
        }
      }
    };
    m_inputThread.start();
    m_outputThread.start();
  }
  
  public void stop() {
    m_inputThread.interrupt();
    m_outputThread.interrupt();
    m_read = false;
    m_write = false;
  }
  
  private synchronized void insert(Object o) {
    m_inputStack.add(0,o);
  }
  
  private synchronized Object remove() {
    if (m_outputStack.isEmpty()) {
      try {
        wait();
      } catch (InterruptedException iex) {}
    }
    return m_outputStack.remove(m_outputStack.size()-1);
  }
  
  public synchronized Object pop() {
    while (m_inputStack.isEmpty()) {
      try {
        wait();
      } catch (InterruptedException iex) {}
    }
    return m_inputStack.remove(m_inputStack.size()-1);
  }
  
  public synchronized void push(Object o) {
    m_outputStack.add(0,o);
    notify();
  }
}

Greets
 
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 02.06.2004, 16:06 Nach oben    #2
Neuer Benutzer
 
Registriert seit: 27.05.2004
Beiträge: 25
Standard

Hast mich gerade auf den zwei Themen erwischt, die ich höchstens am Rand kenne; Doch: Was ist genau die Fehlermeldung? (normalerweise gibts da ja so Zeilennummern...) Wär unter Umständen noch so hilfreich...

mfG Bischi
bischi ist offline  
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 02.06.2004, 16:21 Nach oben    #3
Erfahrener Benutzer
 
Benutzerbild von peschmae
 
Registriert seit: 29.05.2004
Beiträge: 228
Standard

uiuiui, tatsächlich *ggg*

Deadlock heisst es gibt keine Fehlermeldung und das ganze bleibt stehen weil z.B. zwei Threads jeweils auf das Beenden des anderen warten oder so.

Zuerst mal noch ein OT-Hinweis:
Du verwendest Vector - ab Java 1.2 sollte man bevorzugt ArrayLists (oder das entsprechende List-Interface) benutzen.
Vector ist dort nur noch eine Kompatibilitätsklasse. (Wenn du allerdings Java 1.1 Kompatibilität willst ist das durchaus ok )

Scheint mir in Ordnung zu sein - naja, das heisst natürlich nix. Das Thread-Debugging schwierig ist wissen seit einigen Jahren auch die Hurd-Entwickler
Kannst du mal ein bisschen Debugging Ausgaben einfügen versuchen (so println) um zu gucken wo die Threads sind wenn der Fehler auftritt und so?

MfG Peschmä
__________________
Amazon.de | The Java Trap | Freie Software | Freie Software vs. Open Source | GNU Classpath | GCJ | SableVM
"We should forget about small efficiencies, say about 97% of the time: Premature optimization is the root of all evil." - Donald Knuth
peschmae ist offline  
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 02.06.2004, 16:59 Nach oben    #4
Sym
Chefkoch-Mod
 
Benutzerbild von Sym
 
Registriert seit: 30.05.2004
Beiträge: 432
Standard

Zitat:
Zitat von peschmae
Zuerst mal noch ein OT-Hinweis:
Du verwendest Vector - ab Java 1.2 sollte man bevorzugt ArrayLists (oder das entsprechende List-Interface) benutzen.
Vector ist dort nur noch eine Kompatibilitätsklasse. (Wenn du allerdings Java 1.1 Kompatibilität willst ist das durchaus ok )
Hey, das wusste ich auch noch nicht. Aber was ist nun der Unterschied? Die Methoden sehe ja ähnlich oder gleich aus.
__________________
Denk mal darüber nach...

Lars

ACHTUNG: wenn ich von Klassen spreche, könnte ich auch deren Instanzen meinen.
www.linuxforen.de +++ www.macuser.de +++ www.mrunix.de +++ www.lmprojects.de
Sym ist offline  
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 02.06.2004, 17:20 Nach oben    #5
Neuer Benutzer
 
Registriert seit: 27.05.2004
Beiträge: 25
Standard

Zitat:
Deadlock heisst es gibt keine Fehlermeldung und das ganze bleibt stehen weil z.B. zwei Threads jeweils auf das Beenden des anderen warten oder so.
Sagte ja, dass ich höchst bedingt ne Ahnung habe... Schliesse mich aber Peschmäs Vorschlag mit den println an.

mfG Bischi
bischi ist offline  
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 02.06.2004, 17:20 Nach oben    #6
LordOfCodes
Gast
 
Beiträge: n/a
Standard

Danke euch, aber es hat sich schon erledigt.

Wenn jemand die source sehen will, nur sagen.
 
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 02.06.2004, 17:21 Nach oben    #7
Neuer Benutzer
 
Registriert seit: 27.05.2004
Beiträge: 25
Standard

Yepp - man hat nie ausgelernt...

Was war der Fehler?

MfG Bischi
bischi ist offline  
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 02.06.2004, 17:28 Nach oben    #8
LordOfCodes
Gast
 
Beiträge: n/a
Standard

Der Fehler war, dass ich das wait und das notify auf die Klasse und nicht auf das zu sperrende objekt angewendet habe. Und auch dass ich die ganze Methode synchronisiert hab, anstatt nur das verwendete Objekt.


Code:
import java.util.Vector;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.io.ObjectOutputStream;

public class StackSerializer {
  
  ObjectInputStream m_ois;
  ObjectOutputStream m_oos;
  Vector m_inputStack;
  Vector m_outputStack;
  boolean m_read = true;
  boolean m_write = true;
  Thread m_inputThread;
  Thread m_outputThread;
  
  public StackSerializer(InputStream is, OutputStream os) 
  throws Exception {
    m_oos = new ObjectOutputStream(os);
    m_ois = new ObjectInputStream(is);
    m_inputStack = new Vector();
    m_outputStack = new Vector();
    m_inputThread = new Thread() {
      public void run() {
        while (m_read) {
          try {
            insert(m_ois.readObject());
          } catch (Exception ex) {
            insert(ex);
            m_read = false;
          }
        }
      }
    };
    m_outputThread = new Thread() {
      public void run() {
        while (m_write) {
          try {
            m_oos.writeObject(remove());
          } catch (Exception ex) {
            insert(ex);
            m_write = false;
          }
        }
      }
    };
    m_inputThread.start();
    m_outputThread.start();
  }
  
  public void stop() {
    m_inputThread.interrupt();
    m_outputThread.interrupt();
    m_read = false;
    m_write = false;
  }
  
  private void insert(Object o) {
    synchronized(m_inputStack) {
      m_inputStack.add(0,o);
      m_inputStack.notifyAll();
    }
  }
  
  private Object remove() {
    synchronized(m_outputStack) {
      if (m_outputStack.isEmpty()) {
        try {
          m_outputStack.wait();
        } catch (InterruptedException iex) {}
      }
      return m_outputStack.remove(m_outputStack.size()-1);
    }
  }
  
  public Object pop() {
    synchronized (m_inputStack) {
      while (m_inputStack.isEmpty()) {
        try {
          m_inputStack.wait();
        } catch (InterruptedException iex) {}
      }
      return m_inputStack.remove(m_inputStack.size()-1);
    }
  }
  
  public void push(Object o) {
    synchronized(m_outputStack) {
      m_outputStack.add(0,o);
      m_outputStack.notifyAll();
    }
  }
}
 
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 02.06.2004, 17:30 Nach oben    #9
Neuer Benutzer
 
Registriert seit: 27.05.2004
Beiträge: 25
Standard

Was dann natürlich alles blockiert - da gegenseitig gewartet wird (hab ich das richtig verstanden? Hab nur einmal mit Threads ein bisserl rumgebastelt, hat aber nicht wirklich gefunzt...)

mfG Bischi
bischi ist offline  
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 02.06.2004, 17:33 Nach oben    #10
LordOfCodes
Gast
 
Beiträge: n/a
Standard

ja, da hat sich alles gegenseitig gesperrt, oder fehlermeldungen in der art von:
java.lang.IllegalMonitorStateException: current thread not owner
ausgespuckt.

Aber ich bin froh, dass es jetzt funktioniert. Das wird der Grundbaustein der Server/Client Verbindung für mein Online-Game, und so kann ich Objekte hin und her schicken, ohne mich mit der Verbindung abzuquälen..
 
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 16.07.2004, 17:38 Nach oben    #11
makii
Gast
 
Beiträge: n/a
Standard

Zitat:
Zitat von peschmae
Zuerst mal noch ein OT-Hinweis:
Du verwendest Vector - ab Java 1.2 sollte man bevorzugt ArrayLists (oder das entsprechende List-Interface) benutzen.
Vector ist dort nur noch eine Kompatibilitätsklasse. (Wenn du allerdings Java 1.1 Kompatibilität willst ist das durchaus ok )
[OT]
Dazu bleibt mir dann nur noch anzumerken dass ich der Meinung bin, in einer Multi Thread Umgebung sollte man doch lieber Vektor verwenden. Der ist nämlich von Haus aus Thread-save.

Wenn man doch eine Liste nehmen möchte bietet sich die Möglichkeit an eine Service-Funktion der Klasse Collections zu verwenden, um Zugriffe auf diese durch einen Wrapper synchronisieren zu lassen:
http://java.sun.com/j2se/1.5.0/docs/api/java/util/Collections.html#synchronizedList(java.util.List)
[/OT}

Cheers,
makii
 
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 28.08.2004, 14:43 Nach oben    #12
eagle
Gast
 
Beiträge: n/a
Standard

Zitat:
Zitat von makii
Zitat:
Zitat von peschmae
Zuerst mal noch ein OT-Hinweis:
Du verwendest Vector - ab Java 1.2 sollte man bevorzugt ArrayLists (oder das entsprechende List-Interface) benutzen.
Vector ist dort nur noch eine Kompatibilitätsklasse. (Wenn du allerdings Java 1.1 Kompatibilität willst ist das durchaus ok )
Dazu bleibt mir dann nur noch anzumerken dass ich der Meinung bin, in einer Multi Thread Umgebung sollte man doch lieber Vektor verwenden. Der ist nämlich von Haus aus Thread-save.

Wenn man doch eine Liste nehmen möchte bietet sich die Möglichkeit an eine Service-Funktion der Klasse Collections zu verwenden, um Zugriffe auf diese durch einen Wrapper synchronisieren zu lassen:
http://java.sun.com/j2se/1.5.0/docs/api/java/util/Collections.html#synchronizedList(java.util.List)
Das ist so allgemein leider genauso falsch wie der ursprüngliche Hinweis Arraylists statt Vectoren zu verwenden.

Es ist richtig, dass die neuen Collection Klassen (darunter ArrayList und HashMap) gegenüber den alten (darunter Vector und Hashtable) bevorzugt werden sollen. Dafür gibt es hauptsächlich zwei Gründe:

1. die neuen Klassen verwenden Iteratoren statt Enumerationen und sind über diese auch während einer Iteration manipulierbar (z.B. Iterator.remove)
2. die neuen Klassen sind nicht mehr thread-safe und daher im allgemeinen performanter

Wenn man eine multi-threaded Anwendung schreibt, gibt es zwar mit den alten thread-safe Klassen bzw. den Collections.synchronized* Wrappern eine scheinbar einfache Möglichkeit die Anwendung selbst thread-safe zu machen, dies ist jedoch ausser in sehr einfachen Applikationen ein Irrtum und verführt den Programmierer zu dem falschen Glauben sich selbst nicht mehr um korrekte Synchronisierung kümmern zu müssen.

Im allgemeinen müssen neben dem reinen Collection Zugriff auch noch weitere Aktionen synchronisiert werden. Benützt man nun synchronisierte Collection Klassen, so bedeutet dies oft, dass in einem bereits synchronisierten Codeteil eine synchronisierte Collection Methode aufgerufen wird, also zwei ineinandergeschachtelte Locks angefordert werden, wo doch eigentlich bereits das äussere Lock ausreichen würde. Mit dem allgemeinen Hinweis synchronisierte Collections in multi-threaded Applikationen zu verwenden, wird also darüberhinaus auch Performance verschenkt.

cu
 
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Antwort

Lesezeichen


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind an
PingBacks sind an
RefBacks sind aus

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Connection zu MSSQL la-finest Allgemeine Java-Programmierung 2 09.08.2006 09:22
Layout Manager? Java17 Desktop-Applikationen und Grafik 18 01.03.2005 22:36
Connection Conn richtig weitergeben? ghost Allgemeine Java-Programmierung 32 12.02.2005 12:57
Dieselbe Connection aus mehreren Prozessen nutzen? Densi Datenbanken 1 29.10.2004 05:38
[Klassen] Collections bluelight Allgemeine Java-Programmierung 5 24.08.2004 16:39


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:14 Uhr.


Powered by vBulletin® Version 3.7.4 (Deutsch)
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45