fork download
  1. /* package whatever; // don't place package name! */
  2.  
  3. import java.time.LocalTime;
  4. import java.util.*;
  5. import java.util.concurrent.Executors;
  6. import java.util.concurrent.ScheduledExecutorService;
  7. import java.util.concurrent.TimeUnit;
  8. import java.util.concurrent.atomic.AtomicInteger;
  9.  
  10. /* Name of the class has to be "Main" only if the class is public. */
  11. class Ideone
  12. {
  13. private static final int GROUP_SIZE = 3;
  14. private static final Runnable FINISHER = () -> { System.out.println("finisher executing"); };
  15. private static final GroupMonitoringService MONITORING_SERVICE = new GroupMonitoringService(FINISHER, GROUP_SIZE);
  16.  
  17. public static void main(String[] args) {
  18. final ScheduledExecutorService ses = Executors.newScheduledThreadPool(10);
  19. System.out.println("- [" + LocalTime.now() + "] run parent-task...");
  20.  
  21. // create 3 tasks: each task needs 7 seconds.
  22. var tasks = createTasks();
  23. tasks.forEach(t -> ses.scheduleWithFixedDelay(t, 0, 2, TimeUnit.SECONDS));
  24. }
  25.  
  26. private static List<Runnable> createTasks() {
  27. List<Runnable> result = new ArrayList<>();
  28. for (int i = 0; i < GROUP_SIZE; i++) {
  29. RandomWaitTask originalTask = new RandomWaitTask();
  30. CountingRunnable groupedTask = new CountingRunnable(originalTask, "Task " + i);
  31. Runnable notifyingRunnable = () -> {
  32. groupedTask.run();
  33. MONITORING_SERVICE.taskFinished(groupedTask.getGroup());
  34. };
  35. result.add(notifyingRunnable);
  36. }
  37. return result;
  38. }
  39. }
  40.  
  41. class GroupMonitoringService {
  42. // key: group, value: tasks
  43. Map<String, AtomicInteger> finishedTasks = new HashMap<>();
  44. private final Runnable finisher;
  45. private final int groupSize;
  46.  
  47. GroupMonitoringService(Runnable finisher, int groupSize) {
  48. this.finisher = finisher;
  49. this.groupSize = groupSize;
  50. }
  51.  
  52. public synchronized void taskFinished(String group) {
  53. var finishedInGroup = finishedTasks.computeIfAbsent(group, k -> new AtomicInteger());
  54. if (finishedInGroup.incrementAndGet() >= groupSize) {
  55. // scheduling group complete
  56. System.out.printf("Group %s finished executing%n", group);
  57. finisher.run();
  58. finishedTasks.remove(group);
  59. }
  60. }
  61. }
  62.  
  63. interface GroupedRunnable extends Runnable {
  64. String getGroup();
  65. }
  66.  
  67. class CountingRunnable implements GroupedRunnable {
  68. private AtomicInteger counter = new AtomicInteger();
  69. private final Runnable delegate;
  70. private final String taskName;
  71.  
  72. CountingRunnable(Runnable delegate, String taskName) {
  73. this.delegate = delegate;
  74. this.taskName = taskName;
  75. }
  76. public void run() {
  77. System.out.printf("[%s] - Running task %s in group %s%n", LocalTime.now(), taskName, getGroup());
  78. delegate.run();
  79. counter.incrementAndGet();
  80. System.out.printf("[%s] - Running task %s in group %s finished%n", LocalTime.now(), taskName, getGroup());
  81. }
  82.  
  83. @Override
  84. public String getGroup() {
  85. return counter.toString();
  86. }
  87. }
  88.  
  89. class RandomWaitTask implements Runnable {
  90. static final Random RANDOM = new Random();
  91. @Override
  92. public void run() {
  93. try {
  94. Thread.sleep(RANDOM.nextInt(10_000));
  95. } catch (InterruptedException e) {
  96. }
  97. }
  98. }
Time limit exceeded #stdin #stdout #stderr 5s 40092KB
stdin
Standard input is empty
stdout
- [07:40:24.169850] run parent-task...
[07:40:24.231665] - Running task Task 0 in group 0
[07:40:24.234515] - Running task Task 2 in group 0
[07:40:24.233403] - Running task Task 1 in group 0
[07:40:25.355113] - Running task Task 2 in group 1 finished
[07:40:27.357338] - Running task Task 2 in group 1
[07:40:31.316054] - Running task Task 0 in group 1 finished
[7.264s][warning][os,thread] Failed to start thread - pthread_create failed (EAGAIN) for attributes: stacksize: 65536k, guardsize: 0k, detached.
[7.264s][warning][os,thread] Failed to start thread - pthread_create failed (EAGAIN) for attributes: stacksize: 65536k, guardsize: 0k, detached.
[07:40:32.909931] - Running task Task 2 in group 2 finished
[07:40:33.317137] - Running task Task 0 in group 1
[07:40:34.029434] - Running task Task 1 in group 1 finished
Group 1 finished executing
finisher executing
[9.978s][warning][os,thread] Failed to start thread - pthread_create failed (EAGAIN) for attributes: stacksize: 65536k, guardsize: 0k, detached.
[9.978s][warning][os,thread] Failed to start thread - pthread_create failed (EAGAIN) for attributes: stacksize: 65536k, guardsize: 0k, detached.
stderr
Exception in thread "pool-1-thread-1" java.lang.OutOfMemoryError: unable to create native thread: possibly out of memory or process/resource limits reached
	at java.base/java.lang.Thread.start0(Native Method)
	at java.base/java.lang.Thread.start(Thread.java:804)
	at java.base/java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:937)
	at java.base/java.util.concurrent.ThreadPoolExecutor.processWorkerExit(ThreadPoolExecutor.java:1005)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:835)
Exception in thread "pool-1-thread-2" java.lang.OutOfMemoryError: unable to create native thread: possibly out of memory or process/resource limits reached
	at java.base/java.lang.Thread.start0(Native Method)
	at java.base/java.lang.Thread.start(Thread.java:804)
	at java.base/java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:937)
	at java.base/java.util.concurrent.ThreadPoolExecutor.processWorkerExit(ThreadPoolExecutor.java:1005)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:835)