2017-03-03 2 views
0

以下のコードでは、私の主なタスクは、サブタスクが実行を完了するのを待っていません。私はJava Threadを初めて使用しています。だから私はそれを修正することができませんでした。私はそれをgoogleと運が見つかりませんでした。このスレッドの問題を修正するのを手伝ってください。 コード:Javaマルチスレッドの問題

class ExecutorServiceManager{ 
public static ExecutorService getExecutor() { 
    if (executorService == null) { 
     try { 
      lock.lock(); 
      if (executorService == null) { 
       executorService = Executors.newFixedThreadPool(150); 
      } 
     } finally { 
      lock.unlock(); 
     } 
    } 

    if(executorService instanceof ThreadPoolExecutor) { 
     ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executorService; 
     int corePoolSize = threadPoolExecutor.getCorePoolSize(); 
     int maximumPoolSize = threadPoolExecutor.getMaximumPoolSize(); 
     Logger.info(ExecutorServiceManager.class, "ExecutorInfo: CorePoolSize:%s, MaxPoolSize:%s", corePoolSize, maximumPoolSize); 
    } 
    return executorService; 
}} 

class ServiceImpl{ 
ExecutorServiceManager executorServiceManager; 
private void processConversion(String category, Map<String, String> couchDeltaMap, String processKey, String reqId) { 
    try { 
     ProgressVo progressVo = new ProgressVo(); 
     CountDownLatch pgCntxtcountDownLatch = new CountDownLatch(1); 
     executorServiceManager.getExecutor().submit(new MainTask(category, processKey, pgCntxtcountDownLatch, executorServiceManager, progressVo)); 
     Logger.info(ServiceImpl.class, "ExecutorInfo: CorePoolSize:%s, MaxPoolSize:%s", corePoolSize, maximumPoolSize); 
     pgCntxtcountDownLatch.await(); 
    } catch(InterruptedException ie) {} 
     catch(Exception ex) {} 
}} 

class MainTask implements Runnable{ 
@Override 
public void run() {  
    executorService = executorServiceManager.getExecutor(); 
    executorService.submit(new SubTask(progressVo, couchDeltaMap, reqId, executorServiceManager)); 

    //I want the below operation to be executed, if and only the subtask completed its execution. 
    //But the below logger is printing before the subtask completed its execution.  
    Logger.info(MainTask.class, "It got executed before the subtask completed its processing"); 
    pgCntxtcountDownLatch.countDown(); 
}} 

class SubTask implements Runnable{ 
@Override 
public void run() {  
    executorService = executorServiceManager.getExecutor(); 
    doSomeProcess; 
    //It stopped in the middle, and the Main task started executing the remaining operation 
}} 
+1

ダブルチェックロックがない限り、壊れていますいずれにしてもダブルチェックロックを使用しないでください。不要な二重チェックのイディオムが正しく機能することを確認するための手順を実行しましたか? –

+0

あなたがJavaスレッドに慣れていないなら、私は基本的なスレッドクラスに固執します。メカニックが理解できれば、使いやすいクラスを使うことができます。 – efekctive

答えて

0

サブタスクの実行を待つために、あなたの主なタスクを取得するには、あなたがExecutor.submit()によって返さFutureをこの方法を使用することができます。

class MainTask implements Runnable{ 
@Override 
public void run() {  
    executorService = executorServiceManager.getExecutor(); 
    Future subTask = executorService.submit(new SubTask(progressVo, couchDeltaMap, reqId, executorServiceManager)); 
    try{ 
     subTask.get(); //wait for completion of the subtask 
    } catch(Exception e){ 
     //You probably want better exception catching, this is just an example 
    } 

    Logger.info(MainTask.class, "It got executed before the subtask completed its processing"); 
    pgCntxtcountDownLatch.countDown(); 
}} 
+0

あなたのコードをありがとう。私はあなたが言ったようにしてみました。下記のコードをご覧ください。このコードを使用しても、私のコンソールにロガーの「Internal Thread Running Ends」というメッセージは表示されません。 – Ismail

+0

このコメントボックスにコードを追加できませんでした。それで私は答えのセクションに入れました。そのコードを参照してください。このコードを使用しても、私のコンソールにロガーの「Internal Thread Running Ends」というメッセージは表示されません。 MainTaskロガーが処理を完了したことを確認しています。 – Ismail

0
class MainTask implements Runnable{ 
@Override 
public void run() { 
executorService = manager.getExecutor(); 
List<Future<Runnable>> futures = new ArrayList<Future<Runnable>>(); 
while (!pageCntxts.isEmpty()) { 
    popped = pageCntxts.pop(); 
    Future future = executorService.submit(new SubTask(progressVo, couchDeltaMap, reqId,manager)); 
    futures.add(future); 
    if(pageCntxts.isEmpty()) 
     loadPageCntxtWithNext25Records(progressVo); 
    processNum++; 
} 
Logger.debug(MainTask.class, "Internal Thread Running Starts with data size: "+futures.size()); 
for (Future<Runnable> future : futures) { 
    future.get(); 
} 
Logger.debug(MainTask.class, "Internal Thread Running Ends");}} 
関連する問題