Java طويل الجري مهام الخيط المقاطعة مقابل العلم إلغاء

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

سؤال

لدي مهمة تشغيل طويلة، شيء مثل:

public void myCancellableTask() {
    while ( someCondition ) {
       checkIfCancelRequested();
       doSomeWork();
    }
 }

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

شكرًا،

جيف

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

المحلول

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

نصائح أخرى

مشكلة واحدة مع استخدام المقاطعة هو ذلك إذا لم تتحكم في جميع التعليمات البرمجية, ، أنت تدير مخاطر المقاطعة لا تعمل "بشكل صحيح" بسبب فهم شخص آخر كسر كيفية التعامل مع المقاطعات في مكتبتهم. هذا هو API غير مرئي صادرت واجهة برمجة التطبيقات حول التعامل معها interruptالتي أصبحت تعتمد عليها.

في مثالك، لنفترض doSomeWork كان في جرة 3 أضعاف ويبدو أن:

public void doSomeWork() {
    try { 
        api.callAndWaitAnswer() ; 
    } 
    catch (InterruptedException e) { throw new AssertionError(); }
}

الآن عليك التعامل مع AssertionError (أو أيا كان المكتبة التي تستخدمها قد ترمي). لقد رأيت المطورين ذوي الخبرة يرمون جميع أنواع الهراء على مقاطعات الاستقبال! من ناحية أخرى، ربما تبدو الطريقة مثل هذا:

public void doSomeWork() {
    while (true) {
        try { 
            return api.callAndWaitAnswer() ; 
        } 
        catch (InterruptedException e) { /* retry! */ }
    }
}

يؤدي هذا "التعامل غير السليم" من المقاطعة إلى حلقة برنامجك للحلاقة إلى أجل غير مسمى. مرة أخرى، لا ترفض هذا كما سخيف؛ هناك الكثير من آليات معالجة المقاطعة المكسورة هناك.

على الأقل استخدام العلم الخاص بك سيكون غير مرئي تماما لأي مكتبات في الحزب الثالث.

ان ذلك يعتمد على doSomeWork() التنفيذ. هل هذه الحسابات النقية أم أنها (في أي وقت) تنطوي على حظر API (مثل IO) مكالمات؟ لكل bmargulies الإجابة، العديد من عمليات برمجة برمجة التطبيقات في JDK تتلاشى وستنشر الاستثناء الذي انقطع عن المكدس.

لذلك، إذا استطالب العمل في حظر الأنشطة، فأنت بحاجة إلى التقاط المقاطعات في الاعتبار حتى و إن عليك أن تقرر التحكم في العملية باستخدام علم، وينبغي أن تصطاد بشكل مناسب والتعامل مع / نشر المقاطعات.

أبعد من ذلك، إذا كان الاعتماد على علم، تأكد من إعلان علمك volatile دلالات.

أعتقد أنه مسألة تفضيل في معظم الحالات. شخصيا سأذهب إلى العلم يدويا. يمنحك المزيد من السيطرة - على سبيل المثال، بهذه الطريقة تتأكد من أن مؤشر ترابطك لا يترك كائن آخر في حالة غير متناسقة. بالإضافة إلى ذلك، إذا كان الأداء أمرا بالغ الأهمية حقا، ضع في اعتبارك أن استخدام الاستثناءات لهما هادئا (حتى لو كان ضئيلا في 99٪ من الحالات).

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