如何同步2个作业/进程

时间:2014-12-17 18:28:37

标签: java multithreading synchronization executorservice executor

我有一个服务器应用程序,它处理两个完全不同的流程的作业(文件处理)。我调用客户端给出job1或job 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();
    }
}

}

1 个答案:

答案 0 :(得分:1)

而不是每次必须使用单线程方法使用一个执行程序时创建新的执行程序。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来实现此目的。

最初它将为零。如果你打电话给等号,它将会返回。

将闩锁值重置为文件大小后。

将锁存器传递给ProcessFileTask1并在完成后调用latch.countDown()。

下一个作业将进入latch.await(),它将等待所有任务完成。如果已经完成,它将立即从等待中出来。

而不是在上面分支,你应该在这里分支。所以你有更多的控制来同步线程