Guten Tag allerseits :)
Ich habe mal wieder ein Problem, wenn ich ein wenig mit mehreren Threads herumexperimentiere. Ich greife per DIIOP auf einen Domino-Server zu, lasse mir eine Session geben, suche mir eine Datenbank raus und lass mir zu dieser alle Views in einem Vector geben. In einer Schleife, in der ich durch diesen Vector durchiteriere, starte ich für jeden Durchlauf einen neuen Thread und übergebe die jeweilige View. Dieser Thread soll jetzt einfach nur mal durch alle Documents, die in der View sind, durchgehen und die NoteID ausgeben.
Probleme treten auf, wenn kurz nacheinander zwei Threads auf das selbe Document zugreifen, falls dieses in beiden Views vorhanden ist. Einer der Threads wirft eine NotesException in der Zeile, in der er das nächste Document aus der View holen soll.
Zeile:
nextDoc = view.getNextDocument(thisDoc);
thisDoc und nextDoc sind Documents, view ist (wie überraschend) eine View
Exception:
NotesException: The Document is not in View By _Certifier Name
at lotus.domino.NotesExceptionHelper.read(Unknown Source)
at lotus.domino.NotesExceptionHolder._read(Unknown Source)
at lotus.priv.CORBA.iiop.RepImpl.invoke(Unknown Source)
at lotus.priv.CORBA.portable.ObjectImpl._invoke(Unknown Source)
at lotus.domino.corba._IViewStub.getNextDocument(Unknown Source)
at lotus.domino.cso.View.getNextDocument(Unknown Source)
at test.ThreadTests$1TestThread.run(ThreadTests.java:69)
Dieser Fehler is insofern etwas merkwürdig, als dass
1. das Document sehr wohl in der View ist,
2. der Fehler nur auftritt, wenn zum selben Zeitpunkt ein anderer Thread auf dieses Document zugreift,
3. jedes Document auch eine eigene C-Reprästentation hat (weil beide in unterschiedlichen Threads sind) und
4. dieses Problem nicht auftritt, wenn ich jedem Thread dieselbe View übergebe, was mich wohl am meisten verwundert.
Was mir auch noch auffällt ist, dass auch Threads, die keine Exception geworfen haben, nicht immer alle Documents auflisten, sondern vorher aufrufen, als wenn der nextDocument-Aufruf null geliefert hätte (was aber nicht sein dürfte).
Kommt mir aber nicht mit Recycling, das habe am Anfang als Übeltäter vermutet und die Dokumente erst ganz zum Schluss recyclet, aber da es sich bei den Documents jeweils um unabhängige Objekte handelt (handeln sollte), hat sich dadurch nichts geändert.
Leider komme ich nicht um Multithreading herum, so dass ich wohl in irgendeiner Art und Weise eine Lösung für dieses Problem brauch, auf welche Weise auch immer das sein mag. Also dann, ich hoffe auf die ein oder andere Meinung oder Anmerkung, vielleicht hab ich ja auch nur mal wieder Tomaten auf den Augen, wer weiß ;)
Gegen konkurrierenden Zugriff schützt du das Dokument-Objekt am einfachsten über synchronized. Das wird in jedem Java Einführungsbuch erklärt. Natürlich mußt du darauf achtgeben, dass du keine Race Conditions, Dead Locks oder verwandtes einbaust.
Wofür brauchst du mehrere Threads?
Das managen von vielen Threads ist ein faszinierenden Thema, vor dem ich in den letzten Jahren klugerweise zurückgeschreckt bin. In den meisten aktuellen Anwendungen braucht man das nämlich gar nicht. Und in J2EE, Swing, SWT/JFace gibts eingebaute Framework die es einfacher machen. Ein Verständnis für Threads ist grundsätzlich immer eine gute Sache. Die Weigerung, selbstgemanageten multithreaded code zu schreiben aber auch (solange man nicht wirklich weiss, was man tut). Erwarte also nicht, dass es einfach ist.
Ich les zur Zeit 2 Bücher: Java Concurrency in Practice von Brian Goetz sowie Essential C# 2.0 by Mark Michaelis. Das C# Buch dient dabei eindeutig der Entspannung. ;)
Am vielversprechendsten sieht für mich erstmal aus, dass du ein synchronized auf das doc (notes-document) setzt. In Kapitel 22.4 im Handbuch der Javaprogrammierung wird das ziemlich gut erklärt, find ich. (http://www.javabuch.de/)
synchronized (doc) {
ur action
}
Ansonsten hören sich deine (besonders beim 2ten Lesen sehr interessanten Anmerkungen) so an, dass die Probleme etwas mit der internen Implementierung von Notes-RPCs zu tun haben. Notes ist ja bis heute nicht multithreaded. Das System ist eben anders designed. Dokumentiert sind die Probleme aber auch nicht. Vermutlich, weil sehr wenige Leute versuchen, darauf multithreaded zuzugreifen (is auch komplex).
Gruß Axel