fork(3) download
  1. import java.util.ArrayList;
  2. import java.util.List;
  3. import java.util.concurrent.*;
  4. import java.util.concurrent.atomic.AtomicBoolean;
  5.  
  6. public class Main {
  7.  
  8. public static void main(String[] args) throws Exception {
  9. AtomicBoolean processing = new AtomicBoolean(true);
  10.  
  11. new Executor.Builder()
  12. .add(() -> {
  13. System.out.println("TASK 1 Start");
  14. try {
  15. Thread.sleep(2000);
  16. } catch (InterruptedException e) {
  17. e.printStackTrace();
  18. }
  19. System.out.println("TASK 1 Complete");
  20. })
  21. .add(() -> {
  22. System.out.println("TASK 2 Start");
  23. try {
  24. Thread.sleep(500);
  25. } catch (InterruptedException e) {
  26. e.printStackTrace();
  27. }
  28. System.out.println("TASK 2 Complete");
  29. })
  30. .add(() -> {
  31. System.out.println("TASK 3 Start");
  32. try {
  33. Thread.sleep(1000);
  34. } catch (InterruptedException e) {
  35. e.printStackTrace();
  36. }
  37. System.out.println("TASK 3 Complete");
  38. })
  39. .callback(() -> {
  40. System.out.println("All TASK COMPLETED");
  41. processing.set(false);
  42. })
  43. .build()
  44. .execute();
  45.  
  46. while (processing.get()) {
  47. // program runs continuously
  48. }
  49. System.out.println("Program Terminates");
  50. }
  51.  
  52. public static class Executor extends Thread {
  53. private ConcurrentLinkedQueue<Worker> workers;
  54. private Callback callback;
  55. private CountDownLatch latch;
  56.  
  57. private Executor(List<Runnable> tasks, Callback callback) {
  58. super();
  59. this.callback = callback;
  60. workers = new ConcurrentLinkedQueue<>();
  61. latch = new CountDownLatch(tasks.size());
  62.  
  63. for (Runnable task : tasks) {
  64. workers.add(new Worker(task, latch));
  65. }
  66. }
  67.  
  68. public void execute() {
  69. start();
  70. }
  71.  
  72. @Override
  73. public void run() {
  74. while (true) {
  75. Worker worker = workers.poll();
  76. if (worker == null) {
  77. break;
  78. }
  79. worker.start();
  80. }
  81.  
  82. try {
  83. latch.await();
  84. } catch (InterruptedException e) {
  85. e.printStackTrace();
  86. }
  87.  
  88. if (callback != null) {
  89. callback.onComplete();
  90. }
  91. }
  92.  
  93. public static class Builder {
  94. private List<Runnable> tasks = new ArrayList<>();
  95. private Callback callback;
  96.  
  97. public Builder add(Runnable task) {
  98. tasks.add(task);
  99. return this;
  100. }
  101.  
  102. public Builder callback(Callback callback) {
  103. this.callback = callback;
  104. return this;
  105. }
  106.  
  107. public Executor build() {
  108. return new Executor(tasks, callback);
  109. }
  110. }
  111.  
  112. public interface Callback {
  113. void onComplete();
  114. }
  115. }
  116.  
  117. public static class Worker implements Runnable {
  118.  
  119. private AtomicBoolean started;
  120. private Runnable task;
  121. private Thread thread;
  122. private CountDownLatch latch;
  123.  
  124. public Worker(Runnable task, CountDownLatch latch) {
  125. this.latch = latch;
  126. this.task = task;
  127. started = new AtomicBoolean(false);
  128. thread = new Thread(this);
  129. }
  130.  
  131. public void start() {
  132. if (!started.getAndSet(true)) {
  133. thread.start();
  134. }
  135. }
  136.  
  137. @Override
  138. public void run() {
  139. task.run();
  140. latch.countDown();
  141. }
  142. }
  143. }
Success #stdin #stdout 2.19s 2446336KB
stdin
Standard input is empty
stdout
TASK 1 Start
TASK 2 Start
TASK 3 Start
TASK 2 Complete
TASK 3 Complete
TASK 1 Complete
All TASK COMPLETED
Program Terminates