Sto lavorando a un progetto Java in cui è necessario avere più attività in esecuzione in modo asincrono. Sono portato a credere che l'Executor sia il modo migliore per me di farlo, quindi mi sto familiarizzando con esso. (Si è pagato per imparare!) Tuttavia, non mi è chiaro quale sia il modo migliore per realizzare ciò che sto cercando di fare.Procedure consigliate di Java Executor per attività che devono essere eseguite per sempre
Per ragioni, diciamo che ho due attività in esecuzione. Nessuno dei due si prevede che termini, ed entrambi dovrebbero essere eseguiti per tutta la durata della vita dell'applicazione. Sto cercando di scrivere una classe wrapper principale tale che:
- Se una delle attività genera un'eccezione, il wrapper la cattura e riavvia l'attività.
- Se una delle attività viene completata, il wrapper noterà e riavvierà l'attività.
Ora, si deve rilevare che l'implementazione per entrambe le attività si concluderà il codice in run()
in un ciclo infinito che non verrà mai eseguito fino al completamento, con un blocco try/catch che dovrebbe gestire tutte le eccezioni di runtime senza interrompere il ciclo continuo. Sto cercando di aggiungere un altro livello di certezza; se io o qualcuno che mi segue fa qualcosa di stupido che sconfigge queste misure di sicurezza e interrompe il compito, l'applicazione deve reagire in modo appropriato.
C'è una buona pratica per affrontare questo problema che la gente più esperta di me consiglierebbe?
FWIW, ho sbattuto-up questa classe di test:
public class ExecTest {
private static ExecutorService executor = null;
private static Future results1 = null;
private static Future results2 = null;
public static void main(String[] args) {
executor = Executors.newFixedThreadPool(2);
while(true) {
try {
checkTasks();
Thread.sleep(1000);
}
catch (Exception e) {
System.err.println("Caught exception: " + e.getMessage());
}
}
}
private static void checkTasks() throws Exception{
if (results1 == null || results1.isDone() || results1.isCancelled()) {
results1 = executor.submit(new Test1());
}
if (results2 == null || results2.isDone() || results2.isCancelled()) {
results2 = executor.submit(new Test2());
}
}
}
class Test1 implements Runnable {
public void run() {
while(true) {
System.out.println("I'm test class 1");
try {Thread.sleep(1000);} catch (Exception e) {}
}
}
}
class Test2 implements Runnable {
public void run() {
while(true) {
System.out.println("I'm test class 2");
try {Thread.sleep(1000);} catch (Exception e) {}
}
}
}
E 'comportarsi come voglio, ma non so se ci sono trucchi, inefficienze, o addirittura male di testa di attesa per sorprendermi. (In realtà, dato che io sono nuovo a questo, sarei scioccato se non ci fosse qualcosa che non andava/sconsigliabile su di esso).
Tutta la comprensione è accolto favorevolmente.
Se si esegue ciascuno di questi due compiti che il suo esecutore a thread singolo, si può semplicemente mettere 1000 copie del compito in l'esecutore. :-) –
Quindi, se uno dei due compiti fallisce, 999 attendono di prendere il suo posto? Eh. Carino, ma credimi, ho davvero bisogno che questo pollone sia a prova di proiettile come posso farcela. Da qui questa richiesta essenzialmente per una revisione del codice della comunità. – BlairHippo
Ok, sul tema della prova a prova di proiettile: qual è il tuo piano attuale per affrontare le attività che si trovano in deadlock o altri fallimenti di liveness? Solo perché puoi ricominciare più e più volte non significa che continuerà a funzionare, se questi problemi li possono mantenere indefinitamente. –