Java Language


Concurrent Programming (Threads) Java SE 5–Java SE 9 (Early Access)

Java SE 1.0
Java SE 1.1
Java SE 1.2
Java SE 1.3
Java SE 1.4
Java SE 5
Java SE 6
Java SE 7
Java SE 8
Java SE 9 (Early Access)

This draft deletes the entire topic.

Introduction

Concurrent computing is a form of computing in which several computations are executed concurrently instead of sequentially. Java language is designed to support concurrent programming through the usage of threads. Objects and resources can be accessed by multiple threads; each thread can potentially access any object in the program and the programmer must ensure read and write access to objects is properly synchronized between threads.

expand all collapse all

Examples

  • 10

    While Runnable provides a means to wrap code to be executed in a different thread, it has a limitation in that it cannot return a result from the execution. The only way to get some return value from the execution of a Runnable is to assign the result to a variable accessible in a scope outside of the Runnable.

    Callable was introduced in Java 5 as a peer to Runnable. Callable is essentially the same except it has a call method instead of run. The call method has the additional capability to return a result and is also allowed to throw checked exceptions.

    The result from a Callable task submission is available to be tapped via a Future

    Future can be considered a container of sorts that houses the result of the Callable computation. Computation of the callable can carry on in another thread, and any attempt to tap the result of a Future will block and will only return the result once it is available.

    Callable Interface

    public interface Callable<V> {
        V call() throws Exception;
    }
    

    Future

    interface Future<V> {
        V get();
        V get(long timeout, TimeUnit unit);
        boolean cancel(boolean mayInterruptIfRunning);
        boolean isCancelled();
        boolean isDone();
    }
    

    Using Callable and Future example:

    public static void main(String[] args) throws Exception {
        ExecutorService es = Executors.newSingleThreadExecutor();
              
        System.out.println("Time At Task Submission : " + new Date());
        Future<String> result = es.submit(new ComplexCalculator());
        // the call to Future.get() blocks until the result is available.So we are in for about a 10 sec wait now
        System.out.println("Result of Complex Calculation is : " + result.get());
        System.out.println("Time At the Point of Printing the Result : " + new Date());
    }
    

    Our Callable that does a lengthy computation

    public class ComplexCalculator implements Callable<String> {
    
        @Override
        public String call() throws Exception {
            // just sleep for 10 secs to simulate a lengthy computation
            Thread.sleep(10000);            
            System.out.println("Result after a lengthy 10sec calculation");
            return "Complex Result"; // the result 
        }
    }
    

    Output

    Time At Task Submission : Thu Aug 04 15:05:15 EDT 2016
    Result after a lengthy 10sec calculation
    Result of Complex Calculation is : Complex Result
    Time At the Point of Printing the Result : Thu Aug 04 15:05:25 EDT 2016
    

    Other operations permitted on Future

    While get() is the method to extract the actual result Future has provision

    • get(long timeout, TimeUnit unit) defines maximum time period during current thread will wait for a result;
    • To cancel the task call cancel(mayInterruptIfRunning). The flag mayInterrupt indicates that task should be interrupted if it was started and is running right now;
    • To check if task is completed/finished by calling isDone();
    • To check if the lengthy task were cancelled isCancelled().
  • 6

    If you have many tasks to execute, and all these tasks are not dependent of the result of the precedent ones, you can use Multithreading for your computer to do all this tasks at the same time using more processors if your computer can. This can make your program execution faster if you have some big independent tasks.

    class CountAndPrint implements Runnable {
    
        private final String name;
    
        CountAndPrint(String name) {
            this.name = name;
        }
    
        /** This is what a CountAndPrint will do */
        @Override
        public void run() {
            for (int i = 0; i < 10000; i++) {
                System.out.println(this.name + ": " + i);
            }
        }
    
        public static void main(String[] args) {
            // Launching 3 parallel threads
            for (int i = 1; i <= 3; i++) {
                // `start` method will call the `run` method 
                // of CountAndPrint in another thread
                new Thread(new CountAndPrint("Instance " + i)).start();
            }
    
            // Doing some others tasks in the main Thread
            for (int i = 0; i < 10000; i++) {
                System.out.println("main: " + i);
            }
        }
    }
    

    The code of the run method of the various CountAndPrint instances will execute in non predictable order. A snippet of a sample execution might look like this:

    Instance 4: 1
    Instance 2: 1
    Instance 4: 2
    Instance 1: 1
    Instance 1: 2
    Main: 1
    Instance 4: 3
    Main: 2
    Instance 3: 1
    Instance 4: 4
    ...
    
  • 3

    CountDownLatch

    A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.

    1. A CountDownLatch is initialized with a given count.
    2. The await methods block until the current count reaches zero due to invocations of the countDown() method, after which all waiting threads are released and any subsequent invocations of await return immediately.
    3. This is a one-shot phenomenon—the count cannot be reset. If you need a version that resets the count, consider using a CyclicBarrier.

    Key Methods:

    public void await() throws InterruptedException
    

    Causes the current thread to wait until the latch has counted down to zero, unless the thread is interrupted.

    public void countDown()
    

    Decrements the count of the latch, releasing all waiting threads if the count reaches zero.

    Example:

    import java.util.concurrent.*;
    
    class DoSomethingInAThread implements Runnable {
        CountDownLatch latch;
        public DoSomethingInAThread(CountDownLatch latch) {
            this.latch = latch;
        } 
        public void run() {
            try {
                System.out.println("Do some thing");
                latch.countDown();
            } catch(Exception err) {
                err.printStackTrace();
            }
        }
    }
    
    public class CountDownLatchDemo {
        public static void main(String[] args) {
            try {
                int numberOfThreads = 5;
                if (args.length < 1) {
                    System.out.println("Usage: java CountDownLatchDemo numberOfThreads");
                    return;
                }
                try {
                    numberOfThreads = Integer.parseInt(args[0]);
                } catch(NumberFormatException ne) {
                
                }
                CountDownLatch latch = new CountDownLatch(numberOfThreads);
                for (int n = 0; n < numberOfThreads; n++) {
                    Thread t = new Thread(new DoSomethingInAThread(latch));
                    t.start();
                }
                latch.await();
                System.out.println("In Main thread after completion of " + numberOfThreads + " threads");
            } catch(Exception err) {
                err.printStackTrace();
            }
        }
    }
    

    output:

    java CountDownLatchDemo 5
    Do some thing
    Do some thing
    Do some thing
    Do some thing
    Do some thing
    In Main thread after completion of 5 threads
    

    Explanation:

    1. CountDownLatch is initialized with a counter of 5 in Main thread
    2. Main thread is waiting by using await() method.
    3. Five instances of DoSomethingInAThread have been created. Each instance decremented the counter with countDown() method.
    4. Once the counter becomes zero, Main thread will resume
Please consider making a request to improve this example.

Syntax

Syntax

Parameters

Parameters

Still have a question about Concurrent Programming (Threads)? Ask Question

Topic Outline