سؤال

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

public void someFunction(String data)
{
   smallOperation()
   SecondOperation a = new SecondOperation();
   Thread th = new Thread(a);
   th.Start();
}

class SecondOperation implements Runnable
{
  public void run(){
  // doSomething long running
 }
} 
هل كانت مفيدة؟

المحلول

public void someFunction(final String data) {
    shortOperation(data);
    new Thread(new Runnable() {
        public void run(){
            longOperation(data);
        }
    }).start();
}

إذا someFunction يسمى ، سوف JVM تشغيل longOperation إذا

  1. لا يتم تمييز الخيط الذي يعمل عليه شيطان (في الكود أعلاه ليس كذلك)
  2. ال longOperation() لا يرمي استثناء و
  3. لا توجد مكالمات إلى system.exit () في longOperation()

نصائح أخرى

لن يخرج JVM قبل أن ينتهي الخيط. هذا الرمز الذي نشرته لا يجمع حتى ؛ ربما تكون المشكلة في الكود الفعلي.

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

الحل باستخدام عصري جافا

public void someFunction(String data) {
    smallOperation();
    new Thread(() -> {
        // doSomething long running
    }).start();
}

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

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

ExecutorService executor = Executors.newFixedThreadPool(10);
        executor.execute(new Runnable() {
            @Override
            public void run() {
                //your code
            }
        });

إذا حصلت على سؤالك بشكل صحيح ، فأنت تريد الاحتجاج someFunction() ، تنفيذ القصير smallOperation() ، قم بتشغيل موضوع إلى SecondOperation وتأكد من أنه عند إعادته من هذه الوظيفة ، SecondOperation قد اكتمل .

إذا كان التدفق الذي اقترحته صحيحًا ، فأنت بحاجة فقط إلى إضافة السطر التالي:

public void someFunction(String data)
{
   smallOperation()
   SecondOperation a = new SecondOperation();
   Thread th = new Thread(a);
   th.Start();
   th.join(); //add this line to make your MainThread await for this to finish . 
}

class SecondOperation implements Runnable
{
  public void run(){
  // doSomething long running
 }
} 

تفقد هذا مقالة - سلعة ، ينص على أنه "عندما نستدعي طريقة Join () على مؤشر ترابط ، يذهب مؤشر ترابط الاتصال إلى حالة انتظار. يبقى في حالة انتظار حتى ينتهي الخيط المشار إليه". الذي أعتقد ما تحاول تحقيقه

إذا لم يكن الأمر كذلك وتريد إخطارك عند SecondOperation ينتهي ، أقترح عليك استخدام Asynctask

يمكنك إنشاء مؤشر ترابط غير متزامن حقيقي عن طريق إنشاء مؤشر ترابط ثانٍ داخل مؤشر ترابط مؤقت.

(new Thread(new Runnable() { public void run() {
    (new Thread(new Runnable() { public void run()
    {
        /* async thread */
    }})).start();
}})).start();
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top