سؤال

لدي رمز يحتاج إلى القيام بشيء مثل هذا

هناك قائمة من الطبقات لكل طريقة (يتيح القول تنفيذ ()). أحتاج إلى استدعاء هذه الطريقة في كل فصل وهناك مهلة ثابتة لكل استدعاء. الآن، تتم كتابة واحدة من طريقة تنفيذ الفئة بشكل سيء ونتائج في مهلة بسبب عدم خروجه JVM. أنا أشغل الفصل مثل هذا.

java ExecutorServiceTest execute TestClass1 TestClass2 TestClass3

لماذا لا يخرج JVM بعد إكمال تنفيذ التعليمات البرمجية؟

أحصل على الإخراج التالي

In class 1
In Class 2
java.util.concurrent.TimeoutException
at java.util.concurrent.FutureTask$Sync.innerGet(Unknown Source)
at java.util.concurrent.FutureTask.get(Unknown Source)
at ExecutorServiceTest.main(ExecutorServiceTest.java:78)
java.util.concurrent.TimeoutException
at java.util.concurrent.FutureTask$Sync.innerGet(Unknown Source)
at java.util.concurrent.FutureTask.get(Unknown Source)

من الدرجة الثانية تنفيذ الأوقات بعد ذلك، يتم تنفيذ الفئة الثالثة أيضا مرات. لماذا تنفذ الطبقة الثالثة؟

لا يخرج JVM بعد اكتمال التنفيذ. ماهو السبب؟ أيضا لماذا TestClass3 تنفيذ timedout؟

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

class Task implements Callable<String> {
    Object instance;
    Method m;
    Object[] input;
    Task(Object instance, Method m, Object[] input) {
        this.instance = instance;
        this.m = m;
        this.input = input;
    }
    public String call() {
        String s = "initial";
        try {
            m.invoke(instance, input);
        }
        catch (RuntimeException e) {
        }
        catch (Exception e) {
        }
        finally {

        }
        return s;
    }
}


public class ExecutorServiceTest {
    public static void main(String[] args) {
        String methodName = args[0];
        String className;
        List<Object> instanceList = new ArrayList<Object>();
        for (int i=1;i<args.length;i++) {
            className = args[i];
            Object o = null;
            try {
                o = Class.forName(className).newInstance();
            } catch (InstantiationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            instanceList.add(o);
        }
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Iterator<Object> iter = instanceList.iterator();
        while (iter.hasNext()) {
            Object o = iter.next();
            Method m = null;
            try {
                m = o.getClass().getDeclaredMethod(methodName, new Class[] {});
            } catch (SecurityException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            Task t = new Task(o,m,new Object[]{});
            Future<String> fut = executor.submit(t);
            try {
                fut.get(2,TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ExecutionException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (TimeoutException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        executor.shutdown();
    }
}


public class TestClass1 {
    public void execute() {
        System.out.println("In class 1");
    }
}


public class TestClass2 {
    public void execute() {
        System.out.println("In class 2");
        boolean b = true;
        while (b) {

        }
    }
}


public class TestClass3 {
    public void execute() {
        System.out.println("In class 3");
    }
}
هل كانت مفيدة؟

المحلول

ExecutorService.shutdown() لا يوقف فعلا أي منفذين تشغيل / مؤشرات الترابط، يخبر فقط الخدمة بالتوقف عن قبول مهام جديدة:

void shutdown()
يبدأ إيقاف التشغيل المنظم الذي يتم فيه تنفيذ المهام المقدمة مسبقا، ولكن لن يتم قبول أي مهام جديدة. لا يوجد لديه تأثير إضافي إذا أغلقت بالفعل.

مثيل TestClass2 الخاص بك لا يتوقف أبدا عن التشغيل لأنه يحتوي على while(true) حلقة التي لا تملك أبدا.

إذا كنت ترغب في إيقاف تنفيذ التنفيذ على الفور، فيمكنك استخدامها awaitTermination(long timeout, TimeUnit unit) أو shutdownNow().

نصائح أخرى

تحتاج إلى الاتصال executor.shutdown() أو إنشاء خيط الخفي (باستخدام مناسب ThreadFactory مرت ل Executors.newSingleThreadExecutor()

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