ERLEDIGT
NEIN
NEIN
ANTWORTEN
9
9
ZUGRIFFE
360
360
EMPFEHLEN
-
31.01.12 10:28 #1
- Registriert seit
- Nov 2005
- Beiträge
- 213
Hallo,
ich suche derzeit intensiv nach einer Möglichkeit des exklusiven Zugriffs auf ein Objekt innerhalb einer Map.
Es soll also n Threads geben, die auf eine Map zugreifen. In dieser Map sind bestimmte Objekte enthalten. Wenn nun ein Thread sich ein Objekt herausholt, um es zu bearbeiten, soll explizit dieses Objekt für den Zugriff durch andere Threads gesperrt werden.
Ich bin mir allerdings noch nicht sicher, wie ich das steuern soll, ob es da evtl. schon Java Hausmittelchen gibt. Meine bisherige Idee wäre, dass der Thread, der sich das Objekt zum Lesen herausholt, in eine zweite Map ablegt, die nur Objekte beinhaltet, die gerade bearbeitet werden. So könnte ein anderer Thread dort nachsehen, ob es schreibbar ist oder nicht.
Hat jemand schon mal ein ähnliches Problem gelöst?
Grüsse,
chickenwings
-
Code javascript:
1 2 3
synchronize(dein_objekt) { //Code, der sicher auf dem Objekt arbeiten kann, weil kein anderer Thread darauf zugreifen darf }
Weiterführendes:
http://docs.oracle.com/javase/tutori.../syncmeth.html
http://en.wikipedia.org/wiki/Race_condition
http://en.wikipedia.org/wiki/Synchro...ynchronization
http://en.wikipedia.org/wiki/Monitor...hronization%29
http://en.wikipedia.org/wiki/Semapho...programming%29
Edit: Um dir die Problematik nochmal deutlich zu machen:
Das Problem ist, dass das "Nachsehen" auch synchronisiert werden müsste! Denn ansonsten können sich zwei Threads genau beim Nachsehen in die Quere kommen und am Ende denken beide, Sie könnten auf dem Objekt arbeiten.
A und B sind Threads
Code :1 2 3 4 5 6 7 8 9 10
A prüft, ob Objekt in Liste und stellt fest, es ist nicht drin A wird unterbrochen B startet B prüft, ob Objekt in Liste und stellt fest, es ist nicht drin B fügt Objekt zu Liste hinzu B arbeitet auf Objekt B wird unterbrochen A startet A fügt Objekt zu Liste hinzu (ist jetzt doppelt drin) A arbeitet auf Objekt (obwohl B das auch gerade tut)
Geändert von CPoly (31.01.12 um 11:02 Uhr)
-
Ne, das sollten sie eigentlich nicht denken, weil der sync ja auf das gleiche Objekt gemacht wird.
Thread A -> map.get(key).
Thread A -> lock auf obj
Thread B -> map.get(key)
Thread B -> wartet bis obj freigegeben ist.
Thread A -> fertig, aus dem sync-block raus.
Thread B -> wird angestossen und macht weiter.
Kann man schön mit Thread.sleep und thread-dumps nachvollziehen,...
Gruss
slowy
-
-
31.01.12 12:08 #5
- Registriert seit
- Jun 2002
- Ort
- Saarbrücken (Saarland)
- Beiträge
- 9.886
- Blog-Einträge
- 29
Hallo,
Was meinst du mit "soll für andere Threads gesperrt sein" genau? Sollen andere Threads überhaupt keinen Zugriff mehr auf das Objekt bekommen?Es soll also n Threads geben, die auf eine Map zugreifen. In dieser Map sind bestimmte Objekte enthalten. Wenn nun ein Thread sich ein Objekt herausholt, um es zu bearbeiten, soll explizit dieses Objekt für den Zugriff durch andere Threads gesperrt werden.
Oder sollen die anderen Threads zwar noch Zurgiff auf das Objekt haben aber nur noch lesend auf zugreifen können? -> Mutationen wären dann exklusiv nur von dem derzeitigen "Owner" möglich...?
Gruß TomJava rocks!
How to become a good Java Programmer?
Does IT in Java and .Net
The only valid measurement of code quality: WTFs / minute
Blog
Xing
Twitter
-
31.01.12 12:20 #6
- Registriert seit
- Nov 2005
- Beiträge
- 213
Hi Tom,
der Lesezugriff muss nicht exklusiv sein, jedoch der Schreibzugriff. Während des Schreibens, darf das Objekt (logischerweise) auch von keinen anderen Thread gelesen werden. Das Objekt darf nur einen spezifischen Zustand haben, der bekannt ist.
Grüsse,
chickenwings
-
31.01.12 12:28 #7
- Registriert seit
- Jun 2002
- Ort
- Saarbrücken (Saarland)
- Beiträge
- 9.886
- Blog-Einträge
- 29
Hallo,
Hört sich ganz nach java.util.concurrent.locks.ReadWriteLock an...der Lesezugriff muss nicht exklusiv sein, jedoch der Schreibzugriff. Während des Schreibens, darf das Objekt (logischerweise) auch von keinen anderen Thread gelesen werden. Das Objekt darf nur einen spezifischen Zustand haben, der bekannt ist.
Gruß TomJava rocks!
How to become a good Java Programmer?
Does IT in Java and .Net
The only valid measurement of code quality: WTFs / minute
Blog
Xing
Twitter
-
31.01.12 12:48 #8
- Registriert seit
- Jun 2002
- Ort
- Saarbrücken (Saarland)
- Beiträge
- 9.886
- Blog-Einträge
- 29
Hallo,
suchst du vielleicht sowas in der Art?
Der LockingWrapper dient quasi als SynchronizationProxy zum Zugriff auf das BusinessObject
Code java: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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
package de.tutorials.training; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; public class MapGuardExample { public static void main(String[] args) { ConcurrentMap<Integer, LockingWrapper> map = new ConcurrentHashMap<Integer, LockingWrapper>(); map.put(0, new LockingWrapper(new BusinessObject())); int readerCount = 5; int writerCount = 2; ExecutorService es = Executors.newFixedThreadPool(readerCount + writerCount); for (int i = 0; i < readerCount; i++) { es.submit(new Reader(map)); } for (int i = 0; i < writerCount; i++) { es.submit(new Writer(map)); } } static abstract class Worker implements Runnable { private final ConcurrentMap<Integer, LockingWrapper> map; public Worker(ConcurrentMap<Integer, LockingWrapper> map) { this.map = map; } @Override public void run() { while (true) { op(map.get(0)); } } abstract void op(LockingWrapper lockingWrapper); } static class Reader extends Worker { public Reader(ConcurrentMap<Integer, LockingWrapper> map) { super(map); } @Override void op(LockingWrapper lockingWrapper) { lockingWrapper.read(); } } static class Writer extends Worker { public Writer(ConcurrentMap<Integer, LockingWrapper> map) { super(map); } @Override void op(LockingWrapper lockingWrapper) { if (Math.random() < 0.1) { // 10% write probability lockingWrapper.write(); } } } static class BusinessObject { private final AtomicInteger state = new AtomicInteger(); public void write() { System.out.println(Thread.currentThread().getId() + " writes to " + this + " " + state.incrementAndGet()); try { Thread.sleep((long) (1000 * Math.random())); } catch (InterruptedException e) { e.printStackTrace(); } } public void read() { System.out.println(Thread.currentThread().getId() + " reads from " + this + " " + state.get()); } @Override public String toString() { return "BO@"+ System.identityHashCode(this); } } static class LockingWrapper { private final ReadWriteLock lock = new ReentrantReadWriteLock(); private final BusinessObject bo; public LockingWrapper(BusinessObject bo) { this.bo = bo; } public void write() { lock.writeLock().lock(); try { bo.write(); } finally { lock.writeLock().unlock(); } } public void read() { lock.readLock().lock(); try { bo.read(); } finally { lock.readLock().unlock(); } } } }
Ausgabe:
Code :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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
13 reads from BO@753416466 0 10 reads from BO@753416466 0 11 reads from BO@753416466 0 9 reads from BO@753416466 0 12 reads from BO@753416466 0 9 reads from BO@753416466 0 11 reads from BO@753416466 0 10 reads from BO@753416466 0 13 reads from BO@753416466 0 13 reads from BO@753416466 0 13 reads from BO@753416466 0 13 reads from BO@753416466 0 10 reads from BO@753416466 0 11 reads from BO@753416466 0 9 reads from BO@753416466 0 12 reads from BO@753416466 0 9 reads from BO@753416466 0 11 reads from BO@753416466 0 10 reads from BO@753416466 0 13 reads from BO@753416466 0 11 reads from BO@753416466 0 9 reads from BO@753416466 0 12 reads from BO@753416466 0 14 writes to BO@753416466 1 14 writes to BO@753416466 2 14 writes to BO@753416466 3 15 writes to BO@753416466 4 15 writes to BO@753416466 5 15 writes to BO@753416466 6 15 writes to BO@753416466 7 10 reads from BO@753416466 7 10 reads from BO@753416466 7 10 reads from BO@753416466 7 10 reads from BO@753416466 7 10 reads from BO@753416466 7 10 reads from BO@753416466 7 10 reads from BO@753416466 7 10 reads from BO@753416466 7 10 reads from BO@753416466 7 10 reads from BO@753416466 7 10 reads from BO@753416466 7 10 reads from BO@753416466 7 10 reads from BO@753416466 7 10 reads from BO@753416466 7 10 reads from BO@753416466 7 10 reads from BO@753416466 7 10 reads from BO@753416466 7 13 reads from BO@753416466 7 10 reads from BO@753416466 7 13 reads from BO@753416466 7 10 reads from BO@753416466 7 13 reads from BO@753416466 7 10 reads from BO@753416466 7 13 reads from BO@753416466 7 10 reads from BO@753416466 7 13 reads from BO@753416466 7 10 reads from BO@753416466 7 13 reads from BO@753416466 7 10 reads from BO@753416466 7 13 reads from BO@753416466 7 10 reads from BO@753416466 7 13 reads from BO@753416466 7 10 reads from BO@753416466 7 13 reads from BO@753416466 7 10 reads from BO@753416466 7 13 reads from BO@753416466 7 10 reads from BO@753416466 7 13 reads from BO@753416466 7 10 reads from BO@753416466 7 13 reads from BO@753416466 7 10 reads from BO@753416466 7 10 reads from BO@753416466 7 10 reads from BO@753416466 7 11 reads from BO@753416466 7 13 reads from BO@753416466 7 11 reads from BO@753416466 7 12 reads from BO@753416466 7 9 reads from BO@753416466 7 10 reads from BO@753416466 7 11 reads from BO@753416466 7 13 reads from BO@753416466 7 14 writes to BO@753416466 8 14 writes to BO@753416466 9 14 writes to BO@753416466 10 15 writes to BO@753416466 11 ...
Gruß TomJava rocks!
How to become a good Java Programmer?
Does IT in Java and .Net
The only valid measurement of code quality: WTFs / minute
Blog
Xing
Twitter
-
31.01.12 12:56 #9
- Registriert seit
- Nov 2005
- Beiträge
- 213
Hi Tom,
uhi, das sieht schon mal aus, als ginge es in die richtige Richtung.
Ich will mir mal das Beispiel zu Gemüte führen, ist doch eine schon recht ausgewachsene Implementierung.
Vielen Dank für Deine Hinweise
chickenwings
-
02.02.12 00:32 #10
- Registriert seit
- Jun 2002
- Ort
- Saarbrücken (Saarland)
- Beiträge
- 9.886
- Blog-Einträge
- 29
Hallo,
Btw. ein viel einfacherer Ansatz wäre der, in der Map nur Immutable Business Objects abzulegen. Will man einen Map-Eintrag verändern, so muss man eine neues (geändertes) Business Object an der stelle in die ConcurrentMap via map.replace(key, old,new) bzw. map.replace(key,new) einfügen. Die replace Operation verläuft dabei atomar. Deshalb gibt es da auch keine Probleme wenn mehrere Threads konkurrierend auf die Elemete der Map zugreifen.
Siehe: http://docs.oracle.com/javase/6/docs...html#replace(K, V, V)
Gruß TomJava rocks!
How to become a good Java Programmer?
Does IT in Java and .Net
The only valid measurement of code quality: WTFs / minute
Blog
Xing
Twitter
Ähnliche Themen
-
Exklusiver Zugriff auf Datensatz in einer PortgreSQL-Datenbank
Von MScalli im Forum JavaAntworten: 5Letzter Beitrag: 12.11.09, 08:56 -
Zugriff auf Objekt
Von liquidbeats im Forum Flash PlattformAntworten: 2Letzter Beitrag: 02.02.09, 16:51 -
Zugriff auf ein Objekt
Von SaschaT im Forum Flash PlattformAntworten: 4Letzter Beitrag: 13.01.08, 14:14 -
Zugriff auf Objekt (JTextField) einer anderen Klasse
Von UJones im Forum JavaAntworten: 3Letzter Beitrag: 30.03.07, 07:42 -
Zugriff auf Objekt
Von jenno im Forum Flash PlattformAntworten: 7Letzter Beitrag: 02.05.05, 14:24





Zitieren



Login





