جدولة Createxecutorservice مع تأخير متغير
-
19-09-2019 - |
سؤال
لنفترض أن لدي مهمة تسحب العناصر من 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);
}