كيف يمكنني الحصول على Futuretask للعودة بعد تتبعها؟

StackOverflow https://stackoverflow.com/questions/1281237

  •  16-09-2019
  •  | 
  •  

سؤال

في الكود أدناه، أنا أكتسب وقتا مهلة بعد 100 ثانية مثل المقصود. في هذه المرحلة، أتوقع الخروج من التعليمات البرمجية من البرنامج الرئيسي والبرنامج لإنهاء ولكنه يحتفظ بالطباعة إلى وحدة التحكم. كيف يمكنني الحصول على المهمة للتوقف عن التنفيذ بعد المهلة؟

private static final ExecutorService THREAD_POOL = Executors.newCachedThreadPool();

private static <T> T timedCall(Callable<T> c, long timeout, TimeUnit timeUnit) throws InterruptedException, ExecutionException, TimeoutException {
    FutureTask<T> task = new FutureTask<T>(c);
    THREAD_POOL.execute(task);
    return task.get(timeout, timeUnit);
}


public static void main(String[] args) {

    try {
        int returnCode = timedCall(new Callable<Integer>() {
            public Integer call() throws Exception {
                for (int i=0; i < 1000000; i++) {
                    System.out.println(new java.util.Date());
                    Thread.sleep(1000);
                }
                return 0;
            }
        }, 100, TimeUnit.SECONDS);
    } catch (Exception e) {
        e.printStackTrace();
        return;
    }


}
هل كانت مفيدة؟

المحلول

تحتاج إلى إلغاء مهمتك في مهلة (وقطع موضوعها). وهذا ما cancel(true) الطريقة هي ل. في

private static final ExecutorService THREAD_POOL = Executors.newCachedThreadPool();

private static <T> T timedCall(FutureTask<T> task, long timeout, TimeUnit timeUnit) throws InterruptedException, ExecutionException, TimeoutException {
    THREAD_POOL.execute(task);
    return task.get(timeout, timeUnit);
}


public static void main(String[] args) {
        try {
            FutureTask<Integer> task = new FutureTask<Integer>(new Callable<Integer>() {
                public Integer call() throws Exception {
                        for (int i=0; i < 1000000; i++) {
                                if (Thread.interrupted()) return 1;
                                System.out.println(new java.util.Date());
                                Thread.sleep(1000);
                        }
                        return 0;
                }
            });
            int returnCode = timedCall(task, 100, TimeUnit.SECONDS);
        } catch (Exception e) {
                e.printStackTrace();
                task.cancel(true);
        }
        return;
}

نصائح أخرى

يجب أن تكون قادرة على التوقف بسرعة، عند الحاجة.

الرمز الخاص بك:

public Integer call() throws Exception {
    for (int i=0; i < 1000000 && !task.cancelled(); i++) {
        System.out.println(new java.util.Date());
        Thread.sleep(1000); // throws InterruptedException when thread is interrupted
    }
    return 0;
}

قادرة بالفعل على القيام بذلك بفضل الاتصال Thread.sleep(). وبعد النقطة هي أن futureTask.cancel(true) سوف تقاطع الخيط الآخر، ويحتاج الرمز الخاص بك إلى الرد على هذا الانقطاع. Thread.sleep() يفعل ذلك. إذا لم تستخدم Thread.sleep() أو رمز حظر غير مقاطع آخر، يجب عليك التحقق Thread.currentThread().isInterrupted() بنفسك، واستقال في أقرب وقت ممكن (على سبيل المثال عن طريق رمي new InterruptedException()) عندما تجد هذا صحيحا.

تحتاج إلى الاتصال futureTask.cancel(true); من معالج الاستثناء الخاص بك لإلغاء وخيط المقاطعة الذي يدير مهمتك.

نصيحتي هي معرفة آلية انقطاع (هذه مقالة رائعة: التعامل مع intruptedException.) واستخدامها.

بمجرد اكتشاف المهلة، تحتاج إلى استدعاء طريقة الإلغاء (TRUE) لمهمتك ...

أو إيقاف تشغيل المنفذ الخاص بك عن طريق الاتصال إيقاف التشغيل () ...

أو قم بإنهاء VM عن طريق الاتصال System.exit (0)

اعتمادا على احتياجاتك

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top