Dưới đây là một số mã cho thấy việc thực hiện trong tương lai và các Chủ đề .stop() một. Đây là một vấn đề thú vị, và nó chỉ ra sự cần thiết cho một móc trong một ScriptEngine để có thể ngăn chặn bất cứ kịch bản nó đang chạy vì lý do gì. Tôi tự hỏi liệu điều này sẽ phá vỡ các giả định trong hầu hết các triển khai kể từ khi họ giả định eval()
sẽ được thực hiện trong một môi trường đơn luồng (chặn)?
Dù sao, kết quả thực thi mã bên dưới:
// exec with Thread.stop()
$ java ExecJavascript
Java: Starting thread...
JS: Before infinite loop...
Java: ...thread started
Java: Thread alive after timeout, stopping...
Java: ...thread stopped
(program exits)
// exec with Future.cancel()
$ java ExecJavascript 1
Java: Submitting script eval to thread pool...
Java: ...submitted.
JS: Before infinite loop...
Java: Timeout! trying to future.cancel()...
Java: ...future.cancel() executed
(program hangs)
Dưới đây là toàn bộ chương trình:
import java.util.concurrent.*;
import javax.script.*;
public class ExecJavascript
{
private static final int TIMEOUT_SEC = 5;
public static void main(final String ... args) throws Exception
{
final ScriptEngine engine = new ScriptEngineManager()
.getEngineByName("JavaScript");
final String script =
"var out = java.lang.System.out;\n" +
"out.println('JS: Before infinite loop...');\n" +
"while(true) {}\n" +
"out.println('JS: After infinite loop...');\n";
if (args.length == 0) {
execWithThread(engine, script);
}
else {
execWithFuture(engine, script);
}
}
private static void execWithThread(
final ScriptEngine engine, final String script)
{
final Runnable r = new Runnable() {
public void run() {
try {
engine.eval(script);
}
catch (ScriptException e) {
System.out.println(
"Java: Caught exception from eval(): " + e.getMessage());
}
}
};
System.out.println("Java: Starting thread...");
final Thread t = new Thread(r);
t.start();
System.out.println("Java: ...thread started");
try {
Thread.currentThread().sleep(TIMEOUT_SEC * 1000);
if (t.isAlive()) {
System.out.println("Java: Thread alive after timeout, stopping...");
t.stop();
System.out.println("Java: ...thread stopped");
}
else {
System.out.println("Java: Thread not alive after timeout.");
}
}
catch (InterruptedException e) {
System.out.println("Interrupted while waiting for timeout to elapse.");
}
}
private static void execWithFuture(final ScriptEngine engine, final String script)
throws Exception
{
final Callable<Object> c = new Callable<Object>() {
public Object call() throws Exception {
return engine.eval(script);
}
};
System.out.println("Java: Submitting script eval to thread pool...");
final Future<Object> f = Executors.newCachedThreadPool().submit(c);
System.out.println("Java: ...submitted.");
try {
final Object result = f.get(TIMEOUT_SEC, TimeUnit.SECONDS);
}
catch (InterruptedException e) {
System.out.println("Java: Interrupted while waiting for script...");
}
catch (ExecutionException e) {
System.out.println("Java: Script threw exception: " + e.getMessage());
}
catch (TimeoutException e) {
System.out.println("Java: Timeout! trying to future.cancel()...");
f.cancel(true);
System.out.println("Java: ...future.cancel() executed");
}
}
}
Nguồn
2009-10-21 15:06:29
-1 Nếu đường đi không đợi, sẽ không có ngoại lệ. Do đó, nó sẽ không hoạt động với một vòng lặp vô tận. Mã sẽ phải kiểm tra 'Thread.currentThread(). Interrupted()' để các đề xuất của bạn hoạt động. – sfussenegger
Argh, bỏ lỡ điều đó. Điều đó chỉ để lại điểm dừng không được chấp nhận() tôi tin? –
đã thay đổi phiếu bầu của tôi – sfussenegger