BAEL-4559 Stop Execution After Certain Time improvements (#12076)

This commit is contained in:
andresluzu 2022-04-19 22:02:34 -05:00 committed by GitHub
parent 8fd4df52c2
commit 3f78a1e9c0
10 changed files with 303 additions and 0 deletions

View File

@ -0,0 +1,28 @@
package com.baeldung.concurrent.stopexecution;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.TimeUnit;
public class FixedTimeTask implements Runnable {
private static final Logger LOG = LoggerFactory.getLogger(FixedTimeTask.class);
final int fixedTime; // milliseconds
public FixedTimeTask(int fixedTime) {
this.fixedTime = fixedTime;
}
@Override
public void run() {
LOG.info(fixedTime + " milliseconds running task");
try {
TimeUnit.MILLISECONDS.sleep(fixedTime);
} catch (InterruptedException e) {
LOG.info("interrupted");
}
LOG.info("finished");
}
}

View File

@ -0,0 +1,21 @@
package com.baeldung.concurrent.stopexecution;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LongRunningTask implements Runnable {
private static final Logger LOG = LoggerFactory.getLogger(LongRunningTask.class);
@Override
public void run() {
LOG.info("running");
for (int i = 0; i < Long.MAX_VALUE; i++) {
if (Thread.interrupted()) {
LOG.info("stopping");
return;
}
}
LOG.info("finished");
}
}

View File

@ -0,0 +1,23 @@
package com.baeldung.concurrent.stopexecution;
import java.util.Random;
public class Step {
private static int MAX = Integer.MAX_VALUE / 2;
int number;
public Step(int number) {
this.number = number;
}
public void perform() throws InterruptedException {
Random rnd = new Random();
int target = rnd.nextInt(MAX);
while (rnd.nextInt(MAX) != target) {
if (Thread.interrupted()) {
throw new InterruptedException();
}
}
}
}

View File

@ -0,0 +1,31 @@
package com.baeldung.concurrent.stopexecution;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
public class SteppedTask implements Runnable {
private static final Logger LOG = LoggerFactory.getLogger(SteppedTask.class);
private List<Step> steps;
public SteppedTask(List<Step> steps) {
this.steps = steps;
}
@Override
public void run() {
LOG.info("running stepped process");
for (Step step : steps) {
LOG.info("running step " + step.number);
try {
step.perform();
} catch (InterruptedException e) {
LOG.info("interrupting task");
return;
}
}
LOG.info("stepped process finished");
}
}

View File

@ -0,0 +1,95 @@
package com.baeldung.concurrent.stopexecution;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.Timer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class StoppingExecution {
private static final Logger LOG = LoggerFactory.getLogger(StoppingExecution.class);
public static void main(String[] args) {
StoppingExecution.testUsingLoop();
StoppingExecution.testUsingTimer();
StoppingExecution.testUsingFuture();
StoppingExecution.testScheduledExecutor();
StoppingExecution.testSteppedProcess();
}
public static void testUsingLoop() {
LOG.info("using loop started");
long start = System.currentTimeMillis();
long end = start + 30 * 1000; // 30 seconds
while (System.currentTimeMillis() < end) {
LOG.info("running task");
new FixedTimeTask(7 * 1000).run(); // 7 seconds
}
LOG.info("using loop ended");
}
public static void testUsingTimer() {
LOG.info("using timer started");
Thread thread = new Thread(new LongRunningTask());
thread.start();
Timer timer = new Timer();
TimeOutTask timeOutTask = new TimeOutTask(thread, timer);
LOG.info("scheduling timeout in 3 seconds");
timer.schedule(timeOutTask, 3000);
LOG.info("using timer ended");
}
public static void testUsingFuture() {
LOG.info("using future started");
ExecutorService executor = Executors.newSingleThreadExecutor();
Future future = executor.submit(new LongRunningTask());
try {
LOG.info("future get with 7 seconds timeout");
future.get(7, TimeUnit.SECONDS);
} catch (TimeoutException e) {
LOG.info("future timeout");
future.cancel(true);
} catch (Exception e) {
LOG.info("future exception", e);
} finally {
executor.shutdownNow();
}
LOG.info("using future ended");
}
public static void testScheduledExecutor() {
LOG.info("using future schedule executor started");
ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);
Future future = executor.submit(new LongRunningTask());
Runnable cancelTask = () -> future.cancel(true);
LOG.info("cancel task in 3 seconds");
executor.schedule(cancelTask, 3000, TimeUnit.MILLISECONDS);
executor.shutdown();
LOG.info("using future schedule executor ended");
}
public static void testSteppedProcess() {
List<Step> steps = Stream.of(new Step(1), new Step(2), new Step(3), new Step(4)).collect(Collectors.toList());
LOG.info("stepped process started");
Thread thread = new Thread(new SteppedTask(steps));
thread.start();
Timer timer = new Timer();
TimeOutTask timeOutTask = new TimeOutTask(thread, timer);
timer.schedule(timeOutTask, 10000);
}
}

View File

@ -0,0 +1,22 @@
package com.baeldung.concurrent.stopexecution;
import java.util.Timer;
import java.util.TimerTask;
public class TimeOutTask extends TimerTask {
private Thread thread;
private Timer timer;
public TimeOutTask(Thread thread, Timer timer) {
this.thread = thread;
this.timer = timer;
}
@Override
public void run() {
if (thread != null && thread.isAlive()) {
thread.interrupt();
timer.cancel();
}
}
}

View File

@ -0,0 +1,18 @@
package com.baeldung.concurrent.stopexecution;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
public class FixedTimeTaskUnitTest {
@Test
public void run() throws InterruptedException {
long start = System.currentTimeMillis();
Thread thread = new Thread(new FixedTimeTask(10));
thread.start();
thread.join();
long end = System.currentTimeMillis();
assertTrue(end - start >= 10);
}
}

View File

@ -0,0 +1,19 @@
package com.baeldung.concurrent.stopexecution;
import org.junit.Test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class LongRunningTaskUnitTest {
@Test
public void run() {
Thread thread = new Thread(new LongRunningTask());
thread.start();
assertTrue(thread.isAlive());
thread.interrupt();
assertTrue(thread.isInterrupted());
}
}

View File

@ -0,0 +1,26 @@
package com.baeldung.concurrent.stopexecution;
import org.junit.Test;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.junit.Assert.*;
public class SteppedTaskUnitTest {
@Test
public void run() throws InterruptedException {
List<Step> steps = Stream.of(
new Step(1),
new Step(2),
new Step(3))
.collect(Collectors.toList());
Thread thread = new Thread(new SteppedTask(steps));
thread.start();
thread.interrupt();
thread.join();
}
}

View File

@ -0,0 +1,20 @@
package com.baeldung.concurrent.stopexecution;
import org.junit.Test;
import java.util.Timer;
import static org.junit.Assert.assertTrue;
public class TimeOutTaskUnitTest {
@Test
public void run() {
Thread thread = new Thread(new LongRunningTask());
Timer timer = new Timer();
TimeOutTask timeOutTask = new TimeOutTask(thread, timer);
thread.start();
timeOutTask.run();
assertTrue(thread.isInterrupted());
}
}