1

サンプル エグゼキューター サービス

 static class MyRunnable implements Runnable {

    private String serverName;

    public MyRunnable(String serverName) {
        super();
        this.serverName = serverName;
    }

    @Override
    public void run() {
        ...
        conn = new ch.ethz.ssh2.Connection(serverName);
        conn.connect();

        boolean isAuthenticated = conn.authenticateWithPassword(user, pass);
        logger.info("Connecting to " + server);

        if (isAuthenticated == false) {
            logger.info(server + " Please check credentials");
        }

        sess = conn.openSession();
        ...

    }

}

public static void main(String[] args) {
    List<String> serverList = ...;
    ExecutorService executor = Executors.newFixedThreadPool(20);

    for (String serverName : serverList) {
        MyRunnable r = new MyRunnable(serverName);
        executor.execute(r);
    }

    executor.shutdown();
    executor.awaitTermination(1, TimeUnit.HOURS);
}

ここに私のエグゼキュータ サービスのサンプル コードがあります。しかし、このロジックでは、接続に失敗したり、接続に時間がかかりすぎるサーバーに遭遇すると、アプリケーション内でハング時間が発生します。接続に x 時間以上かかる場合は、スレッドを終了/強制終了します。2 秒以内にサーバーに接続しない場合、スレッド タスクを終了するにはどうすればよいですか。

試み

       ThreadPoolExecutor executor = new ThreadPoolExecutor(
                10, 25, 500, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(1));

次のコードを追加しましたが、2000 ミリ秒を超えるとスレッドが終了しないようです。

試行 2

Future<?> future = executor.submit( new task));
            try {
                future.get(2000, TimeUnit.MILLISECONDS); // This waits timeout seconds; returns null
            }

            catch(TimeoutException e) {
                future.cancel(true);
               // System.out.println(server + "name");
            } 
4

4 に答える 4

1

awaitTermination()最初に実行し、次に戻り値を確認してから実行する必要がありますshutdownNow()shutdown()サービスの即時停止を保証するものではなく、新しいジョブの取得を停止し、すべてのジョブが順番に完了するのを待つだけです。shutdownNow()一方、新しいジョブの取得を停止し、実行中のすべてのタスクを積極的に停止しようとし、新しいタスクを開始せず、実行待ちのすべてのジョブのリストを返します。

JavaDocsから:

次のメソッドは、ExecutorService を 2 つのフェーズでシャットダウンします。最初に shutdown を呼び出して着信タスクを拒否し、次に必要に応じて shutdownNow を呼び出して残留タスクをキャンセルします。

 void shutdownAndAwaitTermination(ExecutorService pool) {
   pool.shutdown(); // Disable new tasks from being submitted
   try {
     // Wait a while for existing tasks to terminate
     if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
       pool.shutdownNow(); // Cancel currently executing tasks
       // Wait a while for tasks to respond to being cancelled
       if (!pool.awaitTermination(60, TimeUnit.SECONDS))
           System.err.println("Pool did not terminate");
     }
   } catch (InterruptedException ie) {
     // (Re-)Cancel if current thread also interrupted
     pool.shutdownNow();
     // Preserve interrupt status
     Thread.currentThread().interrupt();
   }
 }
于 2017-06-15T18:12:44.823 に答える