Przesyłam kilka przyszłych zadań przy użyciu usługi CompletionService owiniętej wokół 2 wątku FixedThreadPool ExecutorService, ustawiam następnie ustawić pętlę równą liczbie zadań, które zostały przesłane i używam usługi completement. take() czeka na wszystkich, aby zakończyć lub zawieść. Kłopoty bardzo rzadko się kończą (ale nie wiem dlaczego), więc zmieniłem metodę take() na sondę (300, Timeout.SECONDS), przy założeniu, że wykonanie jednego zadania zajmuje więcej niż 5 minut sondowanie nie powiedzie się, a następnie w końcu wyjdzie z pętli i mogę przejść przez wszystkie futures i zadzwonić do future.cancel (true), aby wymusić anulowanie zadania przestępczego.Jak anulować zadania, które trwają zbyt długo za pomocą usługi CompletionService
Po uruchomieniu kodu i jego wisi, widzę, że ankieta nie działa nieprzerwanie co 5 minut i nie ma więcej zadań, więc zakładam, że dwóch pracowników jest w jakiś sposób zakleszczonych i nigdy nie kończy, i nigdy nie pozwala na dodatkowe zadania zacząć. Ponieważ limit czasu to 5 minut, a było jeszcze 1000 zadań do wykonania, czas potrzebny do przerwania pętli był zbyt długi, dlatego anulowano zadanie.
Więc to, co chcę zrobić, to przerwać/wymuszenie anulowania bieżącego zadania, jeśli nie zostało zakończone w ciągu 5 minut, ale nie widzę w żaden sposób to zrobić.
Ten przykładowy kod przedstawia uproszczoną wersję tego, co Im mówić o
import com.jthink.jaikoz.exception.JaikozException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.*;
public class CompletionServiceTest
{
public static void main(final String[] args)
{
CompletionService<Boolean> cs = new ExecutorCompletionService<Boolean>(Executors.newFixedThreadPool(2));
Collection<Worker> tasks = new ArrayList<Worker>(10);
tasks.add(new Worker(1));
tasks.add(new Worker(2));
tasks.add(new Worker(3));
tasks.add(new Worker(4));
tasks.add(new Worker(5));
tasks.add(new Worker(6));
List<Future<Boolean>> futures = new ArrayList<Future<Boolean>>(tasks.size());
try
{
for (Callable task : tasks)
{
futures.add(cs.submit(task));
}
for (int t = 0; t < futures.size(); t++)
{
Future<Boolean> result = cs.poll(10, TimeUnit.SECONDS);
if(result==null)
{
System.out.println("Worker TimedOut:");
continue;
}
else
{
try
{
if(result.isDone() && result.get())
{
System.out.println("Worker Completed:");
}
else
{
System.out.println("Worker Failed");
}
}
catch (ExecutionException ee)
{
ee.printStackTrace();
}
}
}
}
catch (InterruptedException ie)
{
}
finally
{
//Cancel by interrupting any existing tasks currently running in Executor Service
for (Future<Boolean> f : futures)
{
f.cancel(true);
}
}
System.out.println("Done");
}
}
class Worker implements Callable<Boolean>
{
private int number;
public Worker(int number)
{
this.number=number;
}
public Boolean call()
{
if(number==3)
{
try
{
Thread.sleep(50000);
}
catch(InterruptedException tie)
{
}
}
return true;
}
}
wyjście
Worker Completed:
Worker Completed:
Worker Completed:
Worker Completed:
Worker Completed:
Worker TimedOut:
Done
@ user294896 - czy możesz podać przykładowy kod w małym, samodzielnym przykładzie? – justkt
@justkt Mogę spróbować, może trochę potrwać. –
Dlaczego samo zadanie nie może zdać sobie sprawy, że trwa ono zbyt długo i zostało przerwane? To znacznie uprościłoby sprawy. – trojanfoe