diff --git a/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/notificationforcompletetask/AlertingFutureTask.java b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/notificationforcompletetask/AlertingFutureTask.java new file mode 100644 index 0000000000..bd0bacaa3c --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/notificationforcompletetask/AlertingFutureTask.java @@ -0,0 +1,18 @@ +package com.baeldung.concurrent.notificationforcompletetask; + +import java.util.concurrent.FutureTask; + +public class AlertingFutureTask extends FutureTask { + + private final CallbackInterface callback; + + public AlertingFutureTask(Runnable runnable, Callback callback) { + super(runnable, null); + this.callback = callback; + } + + @Override + protected void done() { + callback.taskDone("task details here"); + } +} diff --git a/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/notificationforcompletetask/AlertingThreadPoolExecutor.java b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/notificationforcompletetask/AlertingThreadPoolExecutor.java new file mode 100644 index 0000000000..029170256f --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/notificationforcompletetask/AlertingThreadPoolExecutor.java @@ -0,0 +1,21 @@ +package com.baeldung.concurrent.notificationforcompletetask; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +public class AlertingThreadPoolExecutor extends ThreadPoolExecutor { + + private final CallbackInterface callback; + + public AlertingThreadPoolExecutor(CallbackInterface callback) { + super(1, 1, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10)); + this.callback = callback; + } + + @Override + protected void afterExecute(Runnable r, Throwable t) { + super.afterExecute(r, t); + callback.taskDone("runnable details here"); + } +} diff --git a/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/notificationforcompletetask/Callback.java b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/notificationforcompletetask/Callback.java new file mode 100644 index 0000000000..fd00a6e116 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/notificationforcompletetask/Callback.java @@ -0,0 +1,10 @@ +package com.baeldung.concurrent.notificationforcompletetask; + +public class Callback implements CallbackInterface { + + public void taskDone(String details){ + System.out.println("task complete: " + details); + // Alerts/notifications go here + } + +} diff --git a/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/notificationforcompletetask/CallbackInterface.java b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/notificationforcompletetask/CallbackInterface.java new file mode 100644 index 0000000000..6df5bc7208 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/notificationforcompletetask/CallbackInterface.java @@ -0,0 +1,5 @@ +package com.baeldung.concurrent.notificationforcompletetask; + +public interface CallbackInterface { + void taskDone(String details); +} diff --git a/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/notificationforcompletetask/RunnableImpl.java b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/notificationforcompletetask/RunnableImpl.java new file mode 100644 index 0000000000..a07254a87f --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/notificationforcompletetask/RunnableImpl.java @@ -0,0 +1,22 @@ +package com.baeldung.concurrent.notificationforcompletetask; + +public class RunnableImpl implements Runnable { + + private final Runnable task; + + private final CallbackInterface callback; + + private final String taskDoneMessage; + + public RunnableImpl(Runnable task, CallbackInterface callback, String taskDoneMessage) { + this.task = task; + this.callback = callback; + this.taskDoneMessage = taskDoneMessage; + } + + public void run() { + task.run(); + callback.taskDone(taskDoneMessage); + } + +} diff --git a/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/notificationforcompletetask/Task.java b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/notificationforcompletetask/Task.java new file mode 100644 index 0000000000..601dfd79b8 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/notificationforcompletetask/Task.java @@ -0,0 +1,9 @@ +package com.baeldung.concurrent.notificationforcompletetask; + +public class Task implements Runnable{ + @Override + public void run() { + System.out.println("Task in progress"); + // Business logic goes here + } +} diff --git a/core-java-modules/core-java-concurrency-basic/src/test/java/com/baeldung/concurrent/notificationforcompletetask/NotificationsForCompleteTasksUnitTest.java b/core-java-modules/core-java-concurrency-basic/src/test/java/com/baeldung/concurrent/notificationforcompletetask/NotificationsForCompleteTasksUnitTest.java new file mode 100644 index 0000000000..f15015da55 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic/src/test/java/com/baeldung/concurrent/notificationforcompletetask/NotificationsForCompleteTasksUnitTest.java @@ -0,0 +1,45 @@ +package com.baeldung.concurrent.notificationforcompletetask; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.FutureTask; + +import org.junit.Test; + +public class NotificationsForCompleteTasksUnitTest { + + @Test + public void whenImplementingRunnable_thenReceiveNotificationOfCompletedTask() { + Task task = new Task(); + Callback callback = new Callback(); + RunnableImpl runnableImpl = new RunnableImpl(task, callback, "ready for next task"); + runnableImpl.run(); + } + + @Test + public void whenUsingCompletableFuture_thenReceiveNotificationOfCompletedTask() { + Task task = new Task(); + Callback callback = new Callback(); + CompletableFuture.runAsync(task) + .thenAccept(result -> callback.taskDone("completion details: " + result)); + } + + @Test + public void whenUsingThreadPoolExecutor_thenReceiveNotificationOfCompletedTask(){ + Task task = new Task(); + Callback callback = new Callback(); + AlertingThreadPoolExecutor executor = new AlertingThreadPoolExecutor(callback); + executor.submit(task); + } + + @Test + public void whenUsingFutureTask_thenReceiveNotificationOfCompletedTask(){ + Task task = new Task(); + Callback callback = new Callback(); + FutureTask future = new AlertingFutureTask(task, callback); + ExecutorService executor = Executors.newSingleThreadExecutor(); + executor.submit(future); + } + +}