[英]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.