Announcement

Collapse
No announcement yet.

Verbesserung der SperrMechanismen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Verbesserung der SperrMechanismen

    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



    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;
    			   }
    			}
    		  }
    	    }
    
    	 }
       }
    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
    Zuletzt editiert von burkut; 10.01.2010, 12:40.
Working...
X