2016-06-11 10 views
2

複数のユーザーから同時にアクセスできるマルチスレッドプログラムを作成中で、競合状態を回避する必要があります。Javaスレッド:マルチスレッド - 競合状態

コード/マルチスレッド:

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 

} 

}

ユーザ1:

public class UserA { 

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

}

ユーザ2:

public class UserB { 

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

}

ユーザ& Bは、同時にデータプロセッサスレッドを呼び出すであろう。 オプション1 & 2は、クラス/自己クラスオブジェクトのロックオブジェクトであり、オプション3はクラスレベルでロックを提供するため、フェース競合状態になることが明らかです。複数のユーザーが同時にオプション3アプリケーションの処理速度が遅くなり、マルチスレッドの全体的な目的が達成されます。

このシナリオを処理する方法については、お読みください。

編集:

いずれかがSendNForgotHelperThreadスレッドオブジェクトに競合状態を処理するために助けてもらえ - このスレッドがループから呼び出されると、各ループの新しいスレッドが開始されているSendNForgotHelperThreadため。

答えて

2

DataProcessorの2つの異なるインスタンスをクラスUserAUserBのスレッドに渡しています。これらのメインメソッドを起動すると、正常に実行されます。あなたのアプリケーションで競合状態は発生しません。

レース条件が共有オブジェクトを渡す必要が生じるために、すなわち、同じオブジェクトを操作するための複数のスレッドと共有オブジェクトは、複数のスレッド

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

間で共有取得するフィールド/属性を持つ必要があります確認してくださいSendNForgotHelperThreadスレッドの5インスタンス - これは競合状態になります – Santosh

+0

'process'メソッドは各スレッドに対して' SendNForgotHelperThread'の新しいインスタンスを1つ作成しません。objDataProcessorのこれら2つのインスタンスは独立しています。競合状態のスレッド。 – Saravana

+0

次に、競合状態を避けるためにオプション1またはオプション2のいずれかが正しいでしょう.3番目のオプションは、クラスレベルのロックとして削除する必要があります。 – Santosh

関連する問題