Monday, August 18, 2014

Example of using ExecutorService/Executors

This example show how to use ExecutorService/Executors.


Executor is an object that executes submitted Runnable tasks. This interface provides a way of decoupling task submission from the mechanics of how each task will be run, including details of thread use, scheduling, etc. An Executor is normally used instead of explicitly creating threads.

ExecutorService is an Executor that provides methods to manage termination and methods that can produce a Future for tracking progress of one or more asynchronous tasks.

An ExecutorService can be shut down, which will cause it to reject new tasks. Two different methods are provided for shutting down an ExecutorService. The shutdown() method will allow previously submitted tasks to execute before terminating, while the shutdownNow() method prevents waiting tasks from starting and attempts to stop currently executing tasks. Upon termination, an executor has no tasks actively executing, no tasks awaiting execution, and no new tasks can be submitted. An unused ExecutorService should be shut down to allow reclamation of its resources.


Example:
package javafxexecutorservice;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

/**
 *
 * @web http://java-buddy.blogspot.com/
 */
public class JavaFXExecutorService extends Application {
    
    ExecutorService executorService = null;

    @Override
    public void start(Stage primaryStage) {
        
        CountDownLatch countDownLatch1 = new CountDownLatch(5);
        CountThread countThread1 = new CountThread("A", countDownLatch1, 5);
        ProgressBar progressBar1 = new ProgressBar();
        progressBar1.progressProperty().bind(countThread1.processProperty);
        
        CountDownLatch countDownLatch2 = new CountDownLatch(10);
        CountThread countThread2 = new CountThread("B", countDownLatch2, 10);
        ProgressBar progressBar2 = new ProgressBar();
        progressBar2.progressProperty().bind(countThread2.processProperty);
        
        CountDownLatch countDownLatch3 = new CountDownLatch(5);
        CountThread countThread3 = new CountThread("C", countDownLatch3, 5);
        ProgressBar progressBar3 = new ProgressBar();
        progressBar3.progressProperty().bind(countThread3.processProperty);
        
        CountDownLatch countDownLatch4 = new CountDownLatch(5);
        CountThread countThread4 = new CountThread("D", countDownLatch4, 5);
        ProgressBar progressBar4 = new ProgressBar();
        progressBar4.progressProperty().bind(countThread4.processProperty);
        
        CountDownLatch countDownLatch5 = new CountDownLatch(5);
        CountThread countThread5 = new CountThread("E", countDownLatch5, 5);
        ProgressBar progressBar5 = new ProgressBar();
        progressBar5.progressProperty().bind(countThread5.processProperty);

        Button btnStart = new Button();
        btnStart.setText("Start");
        btnStart.setOnAction(new EventHandler<ActionEvent>() {
            
            @Override
            public void handle(ActionEvent event) {
                System.out.println("Start");
                executorService = Executors.newFixedThreadPool(2);
                executorService.execute(countThread1);
                executorService.execute(countThread2);
                executorService.execute(countThread3);
                executorService.execute(countThread4);
                executorService.execute(countThread5);
            }
        });
        
        Button btnShutdown = new Button();
        btnShutdown.setText("Shut Down");
        btnShutdown.setOnAction(new EventHandler<ActionEvent>() {
            
            @Override
            public void handle(ActionEvent event) {
                if(executorService != null){
                    System.out.println("Shut Down");
                    executorService.shutdown();
                }
            }
        });
        
        Button btnShutdownNow = new Button();
        btnShutdownNow.setText("Shut Down Now");
        btnShutdownNow.setOnAction(new EventHandler<ActionEvent>() {
            
            @Override
            public void handle(ActionEvent event) {
                if(executorService != null){
                    System.out.println("Shut Down Now");
                    executorService.shutdownNow();
                }
            }
        });
        
        VBox vBox = new VBox();
        vBox.getChildren().addAll(btnStart, btnShutdown, 
            btnShutdownNow, progressBar1, progressBar2, 
            progressBar3, progressBar4, progressBar5);
        
        StackPane root = new StackPane();
        root.getChildren().add(vBox);
        
        Scene scene = new Scene(root, 300, 250);
        
        primaryStage.setTitle("java-buddy.blogspot.com");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
    
}

class CountThread implements Runnable {

    int num_of_count = 5;
    CountDownLatch counter;
    String name;
    
    DoubleProperty processProperty;

    CountThread(String n, CountDownLatch c, int num) {
        name = n;
        counter = c;
        num_of_count = num;
        processProperty = new SimpleDoubleProperty(num_of_count);
    }

    @Override
    public void run() {

        for (int i = 0; i < num_of_count; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                Logger.getLogger(CountThread.class.getName()).log(Level.SEVERE, null, ex);
            }
            
            processProperty.set((double)(counter.getCount())/(double)num_of_count);
            System.out.println(name + " : " + counter.getCount());
            counter.countDown();
            
        }
    }

}

Bind JavaFX ProgressBar.progressProperty() to DoubleProperty in Thread

It's JavaFX version of last example "Java CountDownLatch and Thread" with ProgressBars. It show how to bind ProgressBar.progressProperty() to DoubleProperty in Thread, and update the DoubleProperty in Thread; such that it update ProgressBar automatically.


package javafxexecutorservice;

import java.util.concurrent.CountDownLatch;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

/**
 *
 * @web http://java-buddy.blogspot.com/
 */
public class JavaFXExecutorService extends Application {

    @Override
    public void start(Stage primaryStage) {
        
        CountDownLatch countDownLatch1 = new CountDownLatch(5);
        CountThread countThread1 = new CountThread("A", countDownLatch1, 5);
        ProgressBar progressBar1 = new ProgressBar();
        progressBar1.progressProperty().bind(countThread1.processProperty);
        
        CountDownLatch countDownLatch2 = new CountDownLatch(10);
        CountThread countThread2 = new CountThread("B", countDownLatch2, 10);
        ProgressBar progressBar2 = new ProgressBar();
        progressBar2.progressProperty().bind(countThread2.processProperty);
        
        Button btn = new Button();
        btn.setText("Start");
        btn.setOnAction(new EventHandler<ActionEvent>() {
            
            @Override
            public void handle(ActionEvent event) {
                System.out.println("Start");
                new Thread(countThread1).start();
                new Thread(countThread2).start();
            }
        });
        
        VBox vBox = new VBox();
        vBox.getChildren().addAll(btn, progressBar1, progressBar2);
        
        StackPane root = new StackPane();
        root.getChildren().add(vBox);
        
        Scene scene = new Scene(root, 300, 250);
        
        primaryStage.setTitle("java-buddy.blogspot.com");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
    
}

class CountThread implements Runnable {

    int num_of_count = 5;
    CountDownLatch counter;
    String name;
    
    DoubleProperty processProperty;

    CountThread(String n, CountDownLatch c, int num) {
        name = n;
        counter = c;
        num_of_count = num;
        processProperty = new SimpleDoubleProperty(num_of_count);
    }

    @Override
    public void run() {

        for (int i = 0; i < num_of_count; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                Logger.getLogger(CountThread.class.getName()).log(Level.SEVERE, null, ex);
            }
            
            processProperty.set((double)(counter.getCount())/(double)num_of_count);
            System.out.println(name + " : " + counter.getCount());
            counter.countDown();
            
        }
    }

}

Saturday, August 16, 2014

Java CountDownLatch and Thread

Example to use java.util.concurrent.CountDownLatch, synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.


package javacountdownlatch;

import java.util.concurrent.CountDownLatch;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @web http://java-buddy.blogspot.com/
 */
public class JavaCountDownLatch {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        
        System.out.println("Start counting");
        
        CountDownLatch countDownLatch1 = new CountDownLatch(5);
        CountThread countThread1 = new CountThread("A", countDownLatch1, 5);
        CountDownLatch countDownLatch2 = new CountDownLatch(7);
        CountThread countThread2 = new CountThread("B", countDownLatch2, 7);

        try {
            countDownLatch1.await();
            System.out.println("A finished");
            countDownLatch2.await();
            System.out.println("B finished");
        } catch (InterruptedException ex) {
            Logger.getLogger(JavaCountDownLatch.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println(ex.toString());
        }
    }
}

class CountThread implements Runnable {

    int num_of_count = 5;
    CountDownLatch counter;
    String name;

    CountThread(String n, CountDownLatch c, int num) {
        name = n;
        counter = c;
        num_of_count = num;
        new Thread(this).start();
    }

    @Override
    public void run() {

        for (int i = 0; i < num_of_count; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                Logger.getLogger(CountThread.class.getName()).log(Level.SEVERE, null, ex);
            }
            System.out.println(name + " : " + counter.getCount());
            counter.countDown();
        }
    }

}


- Read JavaFX version, Bind JavaFX ProgressBar.progressProperty() to DoubleProperty in Thread.