2016-06-11 11 views
2

Ich schreibe Multithreading-Programm, das von mehreren Benutzern gleichzeitig zugegriffen werden kann und das Programm Rennen Bedingungen vermeiden muss.Java-Thread: Multithreading - Race-Bedingung

-Code/Multi-Threading:

public class DataProcessor implements Serializable, Runnable { 

private static final long serialVersionUID = 1L; 

public DataProcessor() { 

} 

@Override 
public void run() { 
    process(); 
} 

private void process() { 

    int iSize = 5; 

    for (int iCounter = 0; iCounter < iSize; iCounter++) { 
     DataKey objDataKey = new DataKey(); 
     ArrayList<String> list = //..fetch data method() 
     HashMap<String, String> hmPQdata = //..fetch data method() 

     SendNForgotHelperThread helperThread = new SendNForgotHelperThread(objDataKey, list, hmPQdata); 
     Thread t = new Thread(helperThread); 
     t.start(); 
    } 

} 

class SendNForgotHelperThread implements Runnable { 

    private ArrayList<String> list; 
    private HashMap<String, String> hmPQdata; 
    private DataKey objDataKey; 

    public SendNForgotHelperThread(DataKey objDataKey, ArrayList<String> list, HashMap<String, String> hmPQdata) { 
     this.list = list; 
     this.hmPQdata = hmPQdata; 
     this.objDataKey = objDataKey; 
    } 

    @Override 
    public void run() { 

     try { 

      // Option 1 : synchronized method - SendNForgotHelperThread class object locking 

      DataCollector objDataSenderM = new DataCollector(); 
      objDataSenderM.synchronizedMethodStore(this.objDataKey, this.list, this.hmPQdata); 

      // Option 2 : synchronized block - SendNForgotHelperThread class object locking 

      synchronized (this) { 
       DataCollector objDataSender = new DataCollector(); 
       objDataSender.store(this.objDataKey, this.list, this.hmPQdata); 
      } 

      // Option 3 : Class level locking 

      synchronized (SendNForgotHelperThread.class) { 
       DataCollector objDataSender = new DataCollector(); 
       objDataSender.store(this.objDataKey, this.list, this.hmPQdata); 
      } 

     } catch (Exception iex) { 
      System.out.println("Exception in thread: " + iex.getMessage()); 
     } 
    } 
} 

class DataCollector { 

    public void store(DataKey objDataKey, ArrayList<String> list, HashMap<String, String> hmPQdata) { 

     HashMap<String, String> retrivedValue = (HashMap<String, String>) MemCacheUtil 
       .retrieveFromMemCache(objDataKey.getKey()); 

     retrivedValue.putAll(hmPQdata); 

     MemCacheUtil.addToMemCache(objDataKey.getKey(), retrivedValue, "expTime value"); 

     // Sending data in queue 
     sendDataToQueue(objDataKey, list, hmPQdata); 

    } 

    synchronized void synchronizedMethodStore(DataKey objDataKey, ArrayList<String> list, 
      HashMap<String, String> hmPQdata) { 
     store(objDataKey, list, hmPQdata); 

    } 

} 

class DataKey { 
    private String key; 

    public String getKey() { 
     return key; 
    } 

    public void setKey(String key) { 
     this.key = key; 
    } 
} 

public void sendDataToQueue(DataKey objDataKey, ArrayList<String> list, HashMap<String, String> hmPQdata) { 
    // sending data to queue 

} 

}

Benutzer 1:

public class UserA { 

public static void main(String[] args) { 
    DataProcessor objDataProcessor = new DataProcessor(); 
    Thread thProcessorThread = new Thread(objDataProcessor, "PROCESSOR"); 
    thProcessorThread.start(); 
} 

}

Benutzer 2:

public class UserB { 

public static void main(String[] args) { 
    DataProcessor objDataProcessor = new DataProcessor(); 
    Thread thProcessorThread = new Thread(objDataProcessor, "PROCESSOR"); 
    thProcessorThread.start(); 
} 

}

Benutzer A & B werden Datenprozessor Thread zur gleichen Zeit anrufen. Es ist klar, dass Option 1 & 2 Face-Race-Bedingungen sein werden, da sie Objekt dieser Klassen-/Selbstklassenobjektverriegelung sperren und Option 3 Sperre auf Klassenebene bietet - wenn mehrere Benutzer gleichzeitig auf das Programm zugreifen, dann Option 3 wird die Anwendung verlangsamen und der ganze Zweck des Multithreading wird weiter gehen.

Könnte jemand bitte irgendwelche lesen, wie dieses Szenario zu behandeln.

Edit:

Könnte jemand bitte helfen Race-Bedingung auf SendNForgotHelperThread Thread-Objekt zu handhaben - dieses Thema von der Schleife aufgerufen wird und für jede Schleife neuer Thread gestartet SendNForgotHelperThread wird.

Antwort

2

Sie übergeben zwei verschiedene Instanzen von DataProcessor an die Threads in Klasse UserA und UserB, wenn Sie diese Hauptmethoden starten, wird es normal ausgeführt. Die Race-Bedingung wird in Ihrer Anwendung nicht auftreten.

Für Renn Zustand auftreten Sie das gemeinsame Objekt zu übergeben, dh mehrere Threads auf einem gleichen Objekt und den gemeinsamen Objekten arbeiten sollte Feld haben/Attribut zwischen mehreren Threads

DataProcessor objDataProcessor = new DataProcessor(); 
    Thread thProcessorThread1 = new Thread(objDataProcessor, "PROCESSOR-1"); 
    thProcessorThread1.start(); 
    Thread thProcessorThread2 = new Thread(objDataProcessor, "PROCESSOR-2"); 
    thProcessorThread2.start(); 
+0

Bitte überprüfen geteilt werden 5 Instanz des SendNForgotHelperThread-Threads - dies wird eine Racebedingung haben – Santosh

+0

Es wird nicht, "process" -Methode erstellt eine neue Instanz von 'SendNForgotHelperThread' für jeden Thread, diese zwei Instanzen von objDataProcessor sind unabhängig, Sie würden das gleiche Objekt für mehrere teilen Fäden für Race-Condition. – Saravana

+0

Dann ist entweder Option 1 oder Option 2 korrekt, um Race Condition zu vermeiden und die dritte Option sollte entfernt werden, da sie auf Klassenebene gesperrt ist und die Anwendung verlangsamt. – Santosh