Skip to content
Related Articles

Related Articles

Save Article
Improve Article
Save Article
Like Article

Inner Class And Anonymous Inner Class that Implements Runnable | Concurrent Programming Approach 3

  • Last Updated : 08 Apr, 2019

Prerequisite: Different Approaches to Concurrent Programming in Java

Inner Class that implements Runnable

  1. In this approach, the user physically puts the class definition of the class that implements Runnable inside the class definition of the main class.

    Attention reader! Don’t stop learning now. Get hold of all the important Java Foundation and Collections concepts with the Fundamentals of Java and Java Collections Course at a student-friendly price and become industry ready. To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

    public class OuterClass{
        private class InnerClass implements Runnable{
            public void run(){
            }
        }
    }
    
  2. The run() method is then put inside the inner class and passed to execute method. Execute does not really mean execute. It means available for execution. For instance, if the user has a pool size of 5 and there are 10 tasks in the task queue, the 6th one does not start executing until one of the first five is finished.
    taskList.execute(new InnerClass());
    

Practical Implementation:




import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
  
// Java Program to depict Concurrent
// Programming in action
public class OuterClass {
  
    // Driver method
    public static void main(String[] args)
    {
        new OuterClass().startThreads();
    }
  
    // Starts the threads and calls run method
    // method of the runnable interface
    private void startThreads()
    {
        ExecutorService taskList
            = Executors.newFixedThreadPool(2);
  
        taskList.execute(new InnerClass(1));
        taskList.execute(new InnerClass(2));
        taskList.execute(new InnerClass(3));
        taskList.execute(new InnerClass(4));
        taskList.execute(new InnerClass(5));
        taskList.shutdown();
    }
  
    // Pauses execution allowing time for
    // system to switch back and forth
    private void pause(double seconds)
    {
        try {
            Thread.sleep(Math.round(1000.0 * seconds));
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
  
    // Inner Class
    public class InnerClass implements Runnable {
  
        private int loopLimit;
  
        // Constructor to define
        // different limits
        InnerClass(int loopLimit)
        {
            this.loopLimit = loopLimit;
        }
  
        // Prints thread name and value
        // of the counter variable
        @Override
        public void run()
        {
            for (int i = 0; i < loopLimit; i++) {
                System.out.println(
                    Thread.currentThread().getName()
                    + " Counter: " + i);
                pause(Math.random());
            }
        }
    }
}

Output:




pool-1-thread-1 Counter: 0
pool-1-thread-2 Counter: 0
pool-1-thread-1 Counter: 0
pool-1-thread-2 Counter: 1
pool-1-thread-1 Counter: 1
pool-1-thread-2 Counter: 0
pool-1-thread-2 Counter: 1
pool-1-thread-1 Counter: 2
pool-1-thread-1 Counter: 0
pool-1-thread-2 Counter: 2
pool-1-thread-1 Counter: 1
pool-1-thread-2 Counter: 3
pool-1-thread-1 Counter: 2
pool-1-thread-1 Counter: 3
pool-1-thread-1 Counter: 4

Advantages:

  1. It is easy to access the main application because methods in inner classes can access any public or private methods or instance variables of the outer class.
  2. As with separate classes, the user can pass arguments to the constructor that stores them in instance variables that run uses.

Disadvantages:

  1. There is a disadvantage of tight coupling as the run method is closely tied to this application. The run method cannot be reused elsewhere.
  2. There is a severe danger of race conditions. Inner classes are specifically used when the user wants to access the shared data (data in the main application).

Anonymous Inner Class that implements Runnable

Anonymous Inner Classes: Inner classes are used so frequently in applications that developers often want to shorten the syntax by using Anonymous Inner Classes where the user gives the class definition and instantiate the class all in one fell swoop. Since the anonymous inner classes are inner classes, they have the same pros as inner classes but they are shorter and more succinct. The disadvantages that come with them are that they are a little more confusing to beginners, there are no constructors and that they cannot be reused elsewhere.

Practical Implementation:




import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
  
// Concurrent programming using
// Anonymous Inner Class
public class MyClass {
  
    // Driver method
    public static void main(String[] args)
    {
        new MyClass().startThreads();
    }
  
    // Starting threads with pool size as 2
    private void startThreads()
    {
        ExecutorService taskList
            = Executors.newFixedThreadPool(2);
  
        for (int i = 0; i < 5; i++) {
            int finalI = i + 1;
  
            // Giving the class definition
            // and instantiating it all at once
            taskList.execute(new Runnable() {
  
                // Prints thread name and value
                // of the counter variable
                @Override
                public void run()
                {
                    for (int j = 0; j < finalI; j++) {
                        System.out.println(
                            Thread
                                .currentThread()
                                .getName()
                            + " Counter:" + j);
                        pause(Math.random());
                    }
                }
            });
        }
        taskList.shutdown();
    }
  
    // Pauses execution allowing time for
    // system to switch back and forth
    private void pause(double seconds)
    {
        try {
            Thread.sleep(
                Math.round(1000.0 * seconds));
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Output:

pool-1-thread-1 Counter:0
pool-1-thread-2 Counter:0
pool-1-thread-2 Counter:1
pool-1-thread-1 Counter:0
pool-1-thread-2 Counter:0
pool-1-thread-1 Counter:1
pool-1-thread-2 Counter:1
pool-1-thread-1 Counter:2
pool-1-thread-2 Counter:2
pool-1-thread-2 Counter:3
pool-1-thread-1 Counter:0
pool-1-thread-1 Counter:1
pool-1-thread-1 Counter:2
pool-1-thread-1 Counter:3
pool-1-thread-1 Counter:4



My Personal Notes arrow_drop_up
Recommended Articles
Page :