0

I am new to Java multithreading. I wanted to perform a process executor program. Each process contains zero to many prerequisites (List of String of a Process)

My goal is to run process one by one. And in case the current thread prerequisites are not yet finished, it will wait and resume once all of its prerequisite process are done executing.

I'm not sure if this is possible. Hope you can help me. Please help me make it more simple and easy to understand.

My current program output is: Thread starts Back Up Thread starts Transfer Report Thread starts Archive Report Thread works Back Up Thread waits Transfer Report Thread waits Archive Report Thread finished Back Up Adding Back Up to finished process.

My expected output: Thread starts Back Up Thread starts Transfer Report Thread starts Archive Report Thread works Back Up Thread waits Transfer Report Thread waits Archive Report Thread finished Back Up Adding Back Up to finished process. Thread works Transfer Report Thread finished Transfer Report Adding Transfer Report to finished process. Thread works Archive Report Thread finished Archive Report Adding Archive Report to finished process. == End ==

Below are my current codes:

Main Application

public class ThreadApp {

    public static void main(String[] args) {
        List<EODProcess> eodProcesses = new ArrayList<>();
        eodProcesses.add(new EODProcess("Back Up", new ArrayList<String>()));
        eodProcesses.add(new EODProcess("Archive Report", Arrays.asList("Transfer Report")));
        eodProcesses.add(new EODProcess("Transfer Report", Arrays.asList("Back Up")));
        
        int count = eodProcesses.size();
        CountDownLatch latch = new CountDownLatch(count);
        CyclicBarrier barrier = new CyclicBarrier(count);
        ExecutorService pool = Executors.newFixedThreadPool(count);

        List<String> finishedProcess = new ArrayList<>();
        
        for (EODProcess eodProcess : eodProcesses) {
            pool.execute(() -> {
                try {
                    System.out.println("Thread starts " + eodProcess.getProcess());
                    Thread.sleep(1000);
                    
                    // Wait IF
                    // Process Prerequisite is not empty
                    // Process Prerequisite is not yet finished
                    while(!eodProcess.getPrerequisites().isEmpty() ||
                            !finishedProcess.containsAll(eodProcess.getPrerequisites())) {
                        System.out.println("Thread waits " + eodProcess.getProcess());
                        barrier.await();
                    }
                    
                    System.out.println("Thread works " + eodProcess.getProcess());
                    Thread.sleep(1000);
                    System.out.println("Thread finished " + eodProcess.getProcess());
                
                    System.out.println("Adding " + eodProcess.getProcess() + " to finished process.");
                    finishedProcess.add(eodProcess.getProcess());
                    
                } catch (Exception e) {
                    System.err.println("Worker thread inrerrupted " + eodProcess.getProcess());
                } finally {
                    latch.countDown();
                }
            });
        }

        try {
            // wait for the threads to be done
            latch.await();
            System.out.println("== End == ");
        } catch (InterruptedException e) {
            System.err.println("Starting interrupted");
        }
        pool.shutdown();
    }

}

EODProcess Object

public class EODProcess {

    private String process;
    
    private List<String> prerequisites = new ArrayList<>();
    
    public EODProcess(String process, List<String> prerequisites) {
        this.process = process;
        this.prerequisites.addAll(prerequisites);
    }

    public String getProcess() {
        return process;
    }

    public void setProcess(String process) {
        this.process = process;
    }

    public List<String> getPrerequisites() {
        return prerequisites;
    }

    public void setPrerequisites(List<String> prerequisites) {
        this.prerequisites = prerequisites;
    }

}
Jeipz
  • 1
  • 1
  • https://stackoverflow.com/questions/289434/how-to-make-a-java-thread-wait-for-another-threads-output – JCompetence Feb 11 '21 at 07:14
  • Does this answer your question? [How to make a Java thread wait for another thread's output?](https://stackoverflow.com/questions/289434/how-to-make-a-java-thread-wait-for-another-threads-output) – Shunya Feb 11 '21 at 15:23
  • Im still trying If I can fix my problem with your suggestion. Thank you will let you know if it works. – Jeipz Feb 15 '21 at 00:48
  • Unfortunately it didnt worked for me :( – Jeipz Feb 16 '21 at 05:31
  • If you're only going to run them one at a time, why bother with threading? – NomadMaker Feb 16 '21 at 07:06
  • At first I decided to run them one at a time but right now, I made it run multiple threads so that process execution finish faster. – Jeipz Feb 16 '21 at 07:27

1 Answers1

0

I made my implementation simpler. In my callable object, I do these.

@Override
public String call() throws Exception {
    while (!ThreadApp.finishedProcess.containsAll(eodProcess.getPrerequisites())) {
        System.out.println(eodProcess.getProcess() + " still waiting for prerequisites...");
        Thread.sleep(3000);
    }
    System.out.println(eodProcess.getProcess() + " working...");
    System.out.println(eodProcess.getProcess() + " done!");
    ThreadApp.finishedProcess.add(eodProcess.getProcess());
    return eodProcess.getProcess();
}

Thank you all for your help!

Jeipz
  • 1
  • 1