Чтобы вернуться, продолжить невозвращающий вызов в течение ограниченного времени и < /li>
Убить невозвращающую нить и приносить любые ресурсы, которые он придерживался < /li>
< /ol>
До сих пор. Второе: < /p>
Код: Выделить всё
public static String maybeTimeout(Callable task, long timeOutMs) {
try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
Future taskFuture = executor.submit(task);
try {
return taskFuture.get(timeOutMs, TimeUnit.MILLISECONDS);
} catch (Exception e) {
taskFuture.cancel(true);
System.out.println("Timed out!");
return "Timed out";
}
}
}
Код: Выделить всё
public static Boolean sneakyTrue() {
return true;
}
public static String sleepy() {
return maybeTimeout(
() -> {
var x = 0;
while (sneakyTrue()) {
x = x + 1;
System.out.println("Sleeping again: " + x);
Thread.sleep(1000);
}
return "Unreachable";
},
5000);
}
< /code>
Но не с кодом, который не: < /p>
public static String spinny() {
return maybeTimeout(
() -> {
var x = 0;
var y = 0;
while (sneakyTrue()) {
x = x + 1;
if (x == 0) {
System.out.println("Spinning another maxInt times:" + y);
y = y + 1;
}
}
return "Unreachable";
},
5000);
}
< /code>
Тесты, которые у меня есть, подтверждают это поведение: < /p>
import org.junit.jupiter.api.Test;
import java.util.concurrent.*;
...
@Test
void sleepyShouldBeAbleToTimeout() {
assert (sleepy().equals("Timed out"));
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
@Test
void spinnyShouldBeAbleToTimeout() {
assert (spinny().equals("Timed out"));
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
Подробнее здесь: https://stackoverflow.com/questions/795 ... trary-code