سؤال

لنفترض أن لدي مهمة تسحب العناصر من java.util.concurrent.blockingqueue ومعالجتها.

public void scheduleTask(int delay, TimeUnit timeUnit)
{
    scheduledExecutorService.scheduleWithFixedDelay(new Task(queue), 0, delay, timeUnit);
}

كيف يمكنني جدولة / إعادة جدولة المهمة إذا كان يمكن تغيير التردد بشكل حيوي؟

  • تتمثل الفكرة في اتخاذ تدفق من تحديثات البيانات ونشرها في الدفعة إلى واجهة المستخدم الرسومية
  • يجب أن يكون المستخدم قادرا على تغيير تردد التحديثات
هل كانت مفيدة؟

المحلول

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

نصائح أخرى

يستخدم schedule(Callable<V>, long, TimeUnit) بدلا من scheduleAtFixedRate أو scheduleWithFixedDelay. وبعد ثم تأكد من الاتصال الخاص بك إعادة جدولة نفسها أو مثيل جديد قابل للاستدعاء في مرحلة ما في المستقبل. علي سبيل المثال:

// Create Callable instance to schedule.
Callable<Void> c = new Callable<Void>() {
  public Void call() {
   try { 
     // Do work.
   } finally {
     // Reschedule in new Callable, typically with a delay based on the result
     // of this Callable.  In this example the Callable is stateless so we
     // simply reschedule passing a reference to this.
     service.schedule(this, 5000L, TimeUnit.MILLISECONDS);
   }  
   return null;
  }
}

service.schedule(c);

يتجنب هذا النهج الحاجة إلى إغلاق وإعادة إنشاء ScheduledExecutorService.

لا ينبغي أن تستخدم scheduleAtFixedRate إذا كنت تحاول معالجة العديد من مهام قائمة الانتظار مع فاصل زمني محدد؟ scheduleWithFixedDelay لن تنتظر فقط التأخير المحدد ثم قم بتنفيذ مهمة واحدة من قائمة الانتظار.

في كلتا الحالتين، schedule* الأساليب في أ ScheduledExecutorService سوف يعود أ ScheduledFuture المرجعي. إذا كنت ترغب في تغيير المعدل، فيمكنك إلغاء ScheduledFuture وإعادة جدولة المهمة بمعدل مختلف.

BirthulewithfixeddLay (...) إرجاع Runnablescheduledfuture. من أجل إعادة جدولة ذلك، قد تلغي فقط وإعادة جدولة ذلك. لإعادة جدولة ذلك، قد تلتف فقط Runnablecheduledfuture الطرافة راحة جديدة:

new Runnable() {
    public void run() {
        ((RunnableScheduledFuture)future).run();
    }
};

اضطررت للقيام بذلك مؤخرا باستخدام الجدول المجدول ولم ترغب في التفاف Runnable أو من هذا القبيل. إليك كيف فعلت ذلك:

private ScheduledExecutorService scheduleExecutor;
private ScheduledFuture<?> scheduleManager;
private Runnable timeTask;

public void changeScheduleTime(int timeSeconds){
    //change to hourly update
    if (scheduleManager!= null)
    {
        scheduleManager.cancel(true);
    }
    scheduleManager = scheduleExecutor.scheduleAtFixedRate(timeTask, timeSeconds, timeSeconds, TimeUnit.SECONDS);
}

public void someInitMethod() {

    scheduleExecutor = Executors.newScheduledThreadPool(1);    
    timeTask = new Runnable() {
        public void run() {
            //task code here
            //then check if we need to update task time
            if(checkBoxHour.isChecked()){
                changeScheduleTime(3600);
            }
        }
    };

    //instantiate with default time
    scheduleManager = scheduleExecutor.scheduleAtFixedRate(timeTask, 60, 60, TimeUnit.SECONDS);
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top