簡體   English   中英

如何同步2個作業/流程

[英]how to synchronize 2 jobs/processes

我有一個服務器應用程序,它處理2個作業(文件處理),它們是完全不同的流程。 我調用提供作業1或作業2的客戶端,因此在一定的時間間隔內可能是這2個客戶端。因為文件是從文件夾中選取的,所以我想同步作業,即例如,如果我在觸發后再次快速觸發作業2作業2第一次;其中的文件可能未處理過,所以我不應該再接它們。 而且我寧願等待第一個執行者(執行者服務)完成,然后再觸發另一個作業/執行者。

我嘗試使用存儲作業和執行程序的映射,並嘗試同步映射。但是我不確定如何繼續。為清楚起見,省略了一些代碼。

服務器類:

public class ProcessServer {


public static void main(String[] args) {
    try {
        Integer port = Integer.parseInt(Configuration.getProperty("Environment", "PORT"));
        ServerSocket serverSocket = new ServerSocket(port);
        LOG.info("Process Server listening on PORT: " + port);
        while (true) {
            Socket socket = serverSocket.accept();
            new Thread(new ProcessEvent(socket)).start();
        }
    } catch (Throwable th) {
        LOG.error("Exception occured starting server.", th);
    }
}
}    

ProcessEvent類:

public class ProcessEvent implements Runnable {
   //code to extract argument(event/jobtype) from socket stream
            private void processEvent(Event event) {
    switch (event.getType()) {
        case 1:
            new ProcessJob1().execute(MAP1);
            break;
        case 2:
            new ProcessJob2().execute(MAP2);
            break;
        default:
            break;
    }
}

職位類別1:

public class ProcessJob1 extends Job {

private static Map<String, ExecutorService> isRunning = new HashMap<String, ExecutorService>();

@Override
public void execute(Map<String, Object> jobData) {

    String txn = (String)jobData.get(TYPE);
    ExecutorService executor = null;

    synchronized (isRunning) {
        executor = isRunning.get(type); 
        if (executor != null && !executor.isTerminated()) {
            return;
        }

        executor = Executors.newFixedThreadPool(MAX_THREAD_CNT);
        isRunning.put(type, executor);
    }


    File[] inputFiles = getValidFiles();
    if (inputFiles.length > 0) {
        for (File inputFile : inputFiles) {
            executor.execute(new ProcessFileTask1(inputFile));
        }
    }
    executor.shutdown();
}

}

職位類別2:

public class ProcessJob2 extends Job {

private static ExecutorService executor = null;

@Override
public void execute(Map<String, Object> jobData) {
    if (executor != null && !executor.isTerminated()) {
        return;
    }

    executor = Executors.newFixedThreadPool(2);


    File[] inputFiles = getValidFiles();
    if (inputFiles.length > 0) {
        ExecutorService executor = Executors.newFixedThreadPool(MAX_THREAD_CNT);
        for (File inputFile : inputFiles) {
            executor.execute(new ProcessFileTask2(inputFile));
        }
        executor.shutdown();
    }
}

}

不必每次都使用一個單線程方法使用一個執行器,而不必每次都創建新的執行器。 Executors#newSingleThreadExecutor()

public class ProcessJob1 extends Job {

private static Map<String, ExecutorService> isRunning = new HashMap<String, ExecutorService>();

private static ExecutorService executor = Executors.newFixedThreadPool(MAX);

private static CountDownLatch countDownLatch = new CountDownLatch(0);
@Override
public void execute(Map<String, Object> jobData) {


    File[] inputFiles = getValidFiles();
    countDownLatch.await();

    if (inputFiles.length > 0) {
        countDownLatch = new CountDownLatch(inputFiles.length);
        for (File inputFile : inputFiles) {
              case 1:
                  executor.execute(new ProcessFileTask1(inputFile,countDownLatch));
                  break;
              case 2:
                  executor.execute(new ProcessFileTask2(inputFile,countDownLatch));
                  break;
              default:
                  break;
        }
    }
}

}

您可以使用CountDownLatch來實現。

最初它將是零。 如果您調用wait,它將返回。

之后,將鎖存器值重置為文件大小。

將閂鎖傳遞給ProcessFileTask1並在完成后調用閂鎖。

下一個作業將進入latch.await(),它將等待直到所有任務完成。 如果已經完成,它將立即從等待中出來。

而不是在上面分支,您應該在這里分支。 因此,您擁有更多控制線程的控件

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM