Domanda

Sto cercando di imparare l'API di concorrenza Java e per il mio esercizio voglio programmare un lavoro per eseguire periodicamente ogni x secondi. Il lavoro calcolerà un numero casuale.

Voglio ottenere il risultato dell'attività programmata non appena è terminato. Non sono riuscito a farlo solo con l'API, quindi l'ho violato.

C'è un modo per farlo meglio, senza usare meccanismi di basso livello? Vorrei essere in grado di rimuovere la sincronizzazione MyRandomGiverTask.getResult() E invece usa qualcosa come il ScheduledFuture.get(). Ma nel mio codice programmato non viene mai finito/completato. Questa è la mia soluzione attuale:

class A {
    public static void main() {
        MyRandomGiverTask task = new MyRandomGiverTask(200);
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
        ScheduledFuture<Double> scheduledDouble =
            (ScheduledFuture<Double>) scheduler
                .scheduleAtFixedRate(task, 1, 4, TimeUnit.SECONDS);
        while (true) {
            System.out.println(" >> " + task.getResult());
        }
    }
    public class MyRandomGiverTask implements Runnable {
        MyRandomGiver giver = new MyRandomGiver();
        int param;
        double result;
        public MyRandomGiverTask(int param) { this.param = param; }
        @Override public void run() { result = giver.getRandom(param); }
        public double getResult() {
            try {
                while (result == 0d) {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                return result;
            } finally {
                result = 0d;
            }
        }
    }
}
È stato utile?

Soluzione

Se si desidera calcolare ogni numero casuale, usa un blocco. le attività programmate put()S nuovi numeri casuali in coda e tutto ciò che li vuole può take() loro.

Inoltre, se tu erano Usando qualcosa come la tua soluzione, vorresti usare wait()/notify(), non sleep().

Altri suggerimenti

La tua attività è programmata a velocità fissa. Ciò significa che fino a quando non annulli l'attività, verrà eseguita più e più volte dall'esecutore con una tariffa fissa. L'unica cosa che un tale compito può fare è avere un effetto collaterale. Non può restituire nulla, poiché il futuro che viene restituito dall'esecutore rappresenta tutte le esecuzioni in sospeso dell'attività. Btw, noterai che il schedule Il metodo prende un argomento callabile (che può causare qualcosa), mentre il sceduleAtFixedRate Il metodo prende solo un argomento eseguibile (che restituisce nullo, quindi non può restituire nulla).

Quindi, se si desidera stampare il risultato di ciascuna esecuzione, fai semplicemente l'attività stessa (il runnable) stampare il suo risultato o fare in modo che il risultato sia il risultato in una coda bloccante e fai in modo che il thread principale take Dalla coda. Il thread principale verrà quindi bloccato unito a qualche risultato viene messo in coda.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top