hallo,
ich habe eine Multithread-Anwendung in Java geschrieben. In der Anwendung gibt es 4 Threads inclusive Hauptthread und 4 Buffers. Ein Buffer wird von jeweils zwei Threads zugegriffen, wobei ein Thread füllt es, während der Andere es leert. um die Lese/Schreibe von Buffer zu synchroniesieren habe ich bisher nur synchronized Block gebraucht und das hat bisher funktioniert, aber kriege ich oft Deadlocks, die ich sehr schwer heraus finde.
Das Problem ist dabei aus folgenden Gründen ist der Code sehr unübersichtlich.
1. die Listen Iterieren und
2. Synchronized Block
das ist nur ein Codestück von Gesamten. wie ihr sieht, ist das alles schwer zu lesen. Deswegen möchte ich:
1. ein zentrale SperrMechanismen(eine eigene Klasse oder so wie http://www.java-forum.org/blogs/tfa/...writelock.html), damit ich die ganzen Synchronized Blöcke abkürzen kann.
2. ein zentrale Listen Iterator und Update Mechanismen, die nätürlich mit obigen sperrmechanism zusammen arbeiten muss.
Hätte jemand bitte einen Vorschalg, wie ich dieses Problem lösen kann.
vielen Dank
Burkut
ich habe eine Multithread-Anwendung in Java geschrieben. In der Anwendung gibt es 4 Threads inclusive Hauptthread und 4 Buffers. Ein Buffer wird von jeweils zwei Threads zugegriffen, wobei ein Thread füllt es, während der Andere es leert. um die Lese/Schreibe von Buffer zu synchroniesieren habe ich bisher nur synchronized Block gebraucht und das hat bisher funktioniert, aber kriege ich oft Deadlocks, die ich sehr schwer heraus finde.
Das Problem ist dabei aus folgenden Gründen ist der Code sehr unübersichtlich.
1. die Listen Iterieren und
2. Synchronized Block
Code:
private void mapLockedOperations(ListIterator<ExecutionResource> myfreellEUs) { synchronized (qc.getReadyConsumers()) { // liste der Operationen, die bereit sind, verarbeitet zu werden. ListIterator<Node> readOpList = qc.getReadyConsumers().listIterator(); while (readOpList.hasNext()) { Node node = (Node) readOpList.next(); synchronized (qc.getGetLockedPLEM()) { getLockPlMappingElement(); // Das sind nur die Mapping, die geLocked sind. ListIterator<PlatformElementMapping> lockedPlem = qc.getGetLockedPLEM().listIterator(); while (lockedPlem.hasNext()) { PlatformElementMapping plem = (PlatformElementMapping) lockedPlem.next(); // sind sie gleiche Operation? if (plem.getOperation().getID() == ((Operation) node).getID()) { while (myfreellEUs.hasNext()) { ExecutionResource myEU = myfreellEUs.next(); // sind OperationID von EU in Mapping und aktueller EU // gleich? // wenn ja, ist der EU immernoch frei? if (plem.getExecUnit().getID() == myEU.getID()) { // füge die Mapping zu den zu verarbeitenden // Mappinglist // ein synchronized (qc.getMappingToProcess()) { // System.out.println("locked Plem Länge:" + // lockedPlem.nextIndex()); EList<PlatformElementMapping> myNewMapList = qc.getMappingToProcess(); myNewMapList.add(plem); } System.out.println("EU: " + myEU.getID() + " <---> " + ((Operation) node).getID()); // lösche die Mapping aus der aktuellen Mappingslist // removePLElementMapping(plem); lockedPlem.remove(); // lösche die Operation aus der aktuellen // Operationslist // removeReadyNode(node); readOpList.remove(); // lösche die EU aus free EU List // removeFreeEU(myEU); myfreellEUs.remove(); break; } } break; } } } } } } private void checkForStopThread() { if (modAndQ.getMyDfgNodes().size() == 0 && qc.getReadyConsumers().size() == 0) { try { System.out.println("qc.getReadyConsumers().size(): " + qc.getReadyConsumers().size()); Thread.sleep(5); StopThread(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println("Ausserhalb qc.getReadyConsumers().size(): " + qc.getReadyConsumers().size()); System.out.println("Ausserhalb modAndQ.getMyDfgNodes().size(): " + modAndQ.getMyDfgNodes().size()); } private void mapNormalOperations() { synchronized (qc.getReadyConsumers()) { // liste der Operationen, die bereit sind, verarbeitet zu werden. ListIterator<Node> readOpList = qc.getReadyConsumers().listIterator(); // outReadyOps(); ListIterator<ExecutionResource> myfreellEUs = getFreelistIterEUs(); while (readOpList.hasNext()) { Node node = (Node) readOpList.next(); synchronized (modAndQ.getMyArcMappingPLEM()) { // liste der PlattformElementMapping, die noch zu mappen sind ListIterator<PlatformElementMapping> plemList = modAndQ.getMyArcMappingPLEM().listIterator(); while (plemList.hasNext()) { PlatformElementMapping plem = (PlatformElementMapping) plemList.next(); // sind OperationID in Mapping und die OperationID aktueller // Node/Operation gleich? if (plem.getOperation().getID() == ((Operation) node).getID()) { synchronized (qc.getMyFreeEU()) { // zunächst zum Test würde ich dem ersten freien EU die // erste // zu Verarbeiten bereite Operation zuordnen // Liste der aktuell freien EUs while (myfreellEUs.hasNext()) { ExecutionResource myEU = myfreellEUs.next(); plem.setExecUnit(myEU); System.out.println("EU: " + myEU.getID() + " <---> " + ((Operation) node).getID()); // füge die Mapping zu den zu verarbeitenden // Mappinglist ein synchronized (qc.getMappingToProcess()) { EList<PlatformElementMapping> myNewMapList = qc.getMappingToProcess(); myNewMapList.add(plem); } // lösche die Mapping aus der aktuellen Mappingslist // removePLElementMapping(plem); plemList.remove(); // lösche die Operation aus der aktuellen // Operationslist readOpList.remove(); // lösche die EU aus free EU List myfreellEUs.remove(); break; // } } } break; } } } } } }
1. ein zentrale SperrMechanismen(eine eigene Klasse oder so wie http://www.java-forum.org/blogs/tfa/...writelock.html), damit ich die ganzen Synchronized Blöcke abkürzen kann.
2. ein zentrale Listen Iterator und Update Mechanismen, die nätürlich mit obigen sperrmechanism zusammen arbeiten muss.
Hätte jemand bitte einen Vorschalg, wie ich dieses Problem lösen kann.
vielen Dank
Burkut