2017-09-22 3 views
0

J'ai un exemple simple où j'utilise un ScheduledExecutorService et exécute une tâche à retardement. Je voudrais savoir si c'est un bon moyen de récupérer les données de mon objet caméra.Comment récupérer des données à partir d'un ScheduledExecutorService

public class App { 

    private final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); 
    private final Camera camera = new Camera(); 

    private Object lastPicture; 

    public static void main(String[] args) { 
    App app = new App(); 
    app.takePicture(); 

    // getLatestPicture when I need it on my frontend, in the future. (so image that this part can get called anytime). 
    // I also want to check if this picture is not the same as the last. (I might call getLastPicture multiple times within the second.) 
    Object currentPicture = app.getLastPicture(); 
    if (lastPicture == currentPicture) { 
     System.out.println("Same picture"); 
    } 
    System.out.println(currentPicture); 
    } 

    private void takePicture() { 
    executorService 
     .scheduleWithFixedDelay(takePictureTask(), 0, 1000, TimeUnit.MILLISECONDS); 
    } 

    private Runnable takePictureTask() { 
    return() -> camera.takePicture(); 
    } 

    public Object getLatestPicture() { 
    return camera.getPicture(); 
    } 

} 

Caméra:

public class Camera { 

    private Object picture; 

    public void takePicture() { 
    System.out.println("Taking picture..."); 

    try { 
     Thread.sleep(100); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 

    picture = new Object(); 

    System.out.println("Finished taking picture."); 
    } 

    public Object getPicture() { 
    return picture; 
    } 

} 
+0

C'est ce que 'Callable' est pour https://blogs.oracle.com/corejavatechtips/using-callable-to-return-results-from-runnables – Oleg

+0

' scheduleWithFixedDelay' et 'scheduleAtFixedRate' ne prend pas de' Callable 'param, car ce n'est pas une tâche spécifique qui est exécutée. –

+0

Droit, ce n'était pas clair à partir de votre question. Vous devez rendre 'picture' volatile et alors tout ira bien. – Oleg

Répondre

0

je faire Camera une alimentation BlockingQueue - donc probablement faire un MovieCamera.

private final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); 
    private final BlockingQueue<Object> pictures = new ArrayBlockingQueue<>(); 
    private final Camera camera = new Camera(pictures); 

Vous pouvez ensuite alimenter la file d'attente plutôt que de simplement stocker l'image.

public static class Camera { 
    private final BlockingQueue<Object> pictureQueue; 

    public Camera(BlockingQueue<Object> pictureQueue) { 
     this.pictureQueue = pictureQueue; 
    } 

    public void takePicture() { 
     System.out.println("Taking picture..."); 

     try { 
      Thread.sleep(100); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 

     pictureQueue.put(new Object()); 

     System.out.println("Finished taking picture."); 
    } 

} 

Et vous avez une totale flexibilité dans le traitement de la file d'attente. Vous pouvez obtenir la dernière image en interrogeant la file d'attente jusqu'à ce qu'elle soit vide et sachez s'il y a eu plus de photos automatiquement.

+0

Ouais oke. Tu m'as amené sur un meilleur chemin. Je vais regarder dans les structures de données dans le paquet java.util.concurrent. –