سؤال

كيف لك أن تقتل java.lang.Thread في جافا ؟

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

المحلول

بواسطة الشمس على ماذا إهمال Thread.stop() . وغني في التفاصيل حول لماذا كان هذا الأسلوب السيئ وما ينبغي القيام به لوقف بأمان المواضيع بشكل عام.

والطريقة التي نوصي لاستخدام متغير المشتركة كما علم الذي يطلب من ترابط خلفية لوقف. هذا المتغير يمكن بعد ذلك يتم تعيين من قبل كائن آخر طلب موضوع إنهاء.

نصائح أخرى

وعموما كنت لا ..

وتسأل عليه أن يقطع كل ما تقوم به باستخدام <لأ href = "http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#interrupt٪28٪29" يختلط = "noreferrer"> Thread.interrupt () (وصلة جافادوك)

وشرح جيدا لماذا هو في جافادوك هنا (جافا صلة TechNote لل)

في المواضيع جافا لا يقتل ، ولكن وقف الموضوع يتم في بطريقة تعاونية.الموضوع هو طلب إنهاء و الخيط ثم يمكنك إيقاف التشغيل بأمان.

في كثير من الأحيان volatile boolean المجال هو استخدام الخيط بشكل دوري التحقق وتنتهي عندما يتم تعيين إلى القيمة المقابلة.

أنا لن استخدام boolean للتحقق ما إذا كان موضوع يجب أن إنهاء.إذا كنت تستخدم volatile كما حقل التعديل ، وهذا العمل موثوق بها ، ولكن إذا كان الرمز الخاص بك يصبح أكثر تعقيدا ، بدلا من ذلك يستخدم البعض عرقلة الطرق داخل while حلقة ، قد يحدث هذا الكود لا تنهي أو على الأقل يستغرق وقتا أطول كما قد تريد.

معينة حجب مكتبة أساليب الدعم انقطاع.

كل موضوع بالفعل منطقية العلم توقف الوضع ويجب الاستفادة من ذلك.ويمكن تنفيذ مثل هذا:

public void run() {
   try {
      while (!interrupted()) {
         // ...
      }
   } catch (InterruptedException consumed)
      /* Allow thread to exit */
   }
}

public void cancel() { interrupt(); }

شفرة المصدر مقتبس من جافا التزامن في الممارسة.منذ cancel() الطريقة العامة يمكنك أن تدع موضوع آخر استدعاء هذا الأسلوب كما أردت.

وطريق واحد هو طريق وضع متغير الصف واستخدامه بمثابة الحارس.

Class Outer {
    public static volatile flag = true;

    Outer() {
        new Test().start();
    }
    class Test extends Thread {

        public void run() {
            while (Outer.flag) {
                //do stuff here
            }
        }
    }

}

وتعيين متغير الطبقة الخارجية، أي العلم = صحيح في المثال أعلاه. تعيين إلى false إلى 'قتل' في الموضوع.

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

Thread f = <A thread to be stopped>
Method m = Thread.class.getDeclaredMethod( "stop0" , new Class[]{Object.class} );
m.setAccessible( true );
m.invoke( f , new ThreadDeath() );

أريد أن أضيف عدة ملاحظات على أساس التعليقات التي تراكمت.

  1. الخيط.وقف() سوف تتوقف الموضوع إذا كان مدير الأمن يسمح بذلك.
  2. الخيط.وقف() أمر خطير.وقد قلت ذلك ، إذا كنت تعمل في جي والبيئة لديك أي سيطرة على رمز يطلق ، قد يكون من الضروري.
  3. يجب أن لا تتوقف أبدا التوقف عن حاوية ترابط.إذا كنت ترغب في تشغيل التعليمات البرمجية التي تميل إلى شنق ، (بعناية) تبدأ من جديد الخيط الخفي ورصد ذلك القتل إذا لزم الأمر.
  4. وقف() يخلق جديد ThreadDeath خطأ على الدعوة موضوع ومن ثم يسبب هذا الخطأ ليتم تطبيقها على الهدف الخيط.ولذلك تتبع المكدس عموما لا قيمة لها.
  5. في JRE 6, stop() الشيكات مع مدير الأمن ثم يدعو stop1() أن يدعو stop0().stop0() هو التعليمات البرمجية الأصلية.

وكنت التصويت لThread.stop().

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

وكل ذلك وبامكانه ان يفعل معالجة استجابة التي يمكن أن تكون وحدة المعالجة المركزية مكثفة. ولكم، ومطور، لا يستطيع حتى وقف ذلك، لأنه لا يمكن رمي خطوط if (Thread.currentThread().isInterrupted()) في كافة التعليمات البرمجية.

وحتى عدم القدرة على التوقف بالقوة موضوع هو غريب.

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

لهذا الغرض أنا خلقت jkillthread . انظر تعليماتها للاستخدام.

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

ولكن هذا هو مجرد "لائق", وليست مطلقة, لأن رمز يمكن أن قبض على ThreadDeath خطأ (أو أيا كان استثناء صراحة رمي) ، وليس rethrow مثل نبيل الخيط من المفترض أن تفعل.إذن خلاصة القول هي AFAIA لا يوجد المطلق تفشل آمنة.

وليس هناك طريقة لقتل برشاقة الموضوع.

ويمكنك محاولة لقطع الخيط، واستراتيجية واحدة العموم هو استخدام حبوب منع الحمل السم على رسالة موضوع لوقف نفسها

public class CancelSupport {
    public static class CommandExecutor implements Runnable {
            private BlockingQueue<String> queue;
            public static final String POISON_PILL  = “stopnow”;
            public CommandExecutor(BlockingQueue<String> queue) {
                    this.queue=queue;
            }
            @Override
            public void run() {
                    boolean stop=false;
                    while(!stop) {
                            try {
                                    String command=queue.take();
                                    if(POISON_PILL.equals(command)) {
                                            stop=true;
                                    } else {
                                            // do command
                                            System.out.println(command);
                                    }
                            } catch (InterruptedException e) {
                                    stop=true;
                            }
                    }
                    System.out.println(“Stopping execution”);
            }

    }

و}

BlockingQueue<String> queue=new LinkedBlockingQueue<String>();
Thread t=new Thread(new CommandExecutor(queue));
queue.put(“hello”);
queue.put(“world”);
t.start();
Thread.sleep(1000);
queue.put(“stopnow”);

http://anandsekar.github.io/cancel-support-for-threads /

وعموما أنت لا تقتل، ووقف، أو يقطع خيط (أو تحقق هيتر انقطع عليه ())، ولكن السماح لها إنهاء بشكل طبيعي.

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

وبهذه الطريقة يمكنك بأمان قتل :) الموضوع.

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

هناك نوعان الحلول المناسبة للرقابة المواضيع الإنهاءات:

  • استخدام مشترك متقلبة العلم
  • استخدام زوج من الموضوع.يقطع() والخيط.توقف() الأساليب.

جيد و شرح مفصل من القضايا المتعلقة المفاجئ المواضيع إنهاء فضلا عن أمثلة من الخطأ والحق من حلول التحكم المواضيع الإنهاء يمكن العثور عليها هنا:

https://www.securecoding.cert.org/confluence/display/java/THI05-J.+Do+not+use+Thread.stop%28%29+to+terminate+threads

وهنا بضعة جيدة يقرأ حول هذا الموضوع:

ماذا تفعل مع InterruptedException؟

اغلاق المواضيع نظيفة

'قتل على موضوع' ليس عبارة الصحيحة لاستخدامها. هنا هو طريقة واحدة يمكننا تنفيذ رشيقة إنجاز / الخروج من موضوع على الإرادة:

وRunnable التي اعتدت:

class TaskThread implements Runnable {

    boolean shouldStop;

    public TaskThread(boolean shouldStop) {
        this.shouldStop = shouldStop;
    }

    @Override
    public void run() {

        System.out.println("Thread has started");

        while (!shouldStop) {
            // do something
        }

        System.out.println("Thread has ended");

    }

    public void stop() {
        shouldStop = true;
    }

}

والطبقة اثار:

public class ThreadStop {

    public static void main(String[] args) {

        System.out.println("Start");

        // Start the thread
        TaskThread task = new TaskThread(false);
        Thread t = new Thread(task);
        t.start();

        // Stop the thread
        task.stop();

        System.out.println("End");

    }

}

وأنا لم تحصل على المقاطعة للعمل في الروبوت، لذلك تستخدم هذه الطريقة، ويعمل تماما:

boolean shouldCheckUpdates = true;

private void startupCheckForUpdatesEveryFewSeconds() {
    Thread t = new Thread(new CheckUpdates());
    t.start();
}

private class CheckUpdates implements Runnable{
    public void run() {
        while (shouldCheckUpdates){
            //Thread sleep 3 seconds
            System.out.println("Do your thing here");
        }
    }
}

 public void stop(){
        shouldCheckUpdates = false;
 }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top