Main App Implements Runnable | Concurrent Programming Approach 2
Last Updated :
08 Apr, 2019
Prerequisite: Different Approaches to Concurrent Programming in Java
Let’s look at the second approach in detail.
- The user has the main class that implements runnable which is a promise to the compiler that the class will have a run method.
public class MyClass implements Runnable{
public void run(){
}
}
- The user then passes a reference to the main application to the execute method using the this keyword.
taskList.execute(this)
This is the way to convey to the compiler that when it gets around to running a particular task, call it’s the respective run method.
- The advantage of this approach over approach one is that the run method can call methods in the main application including the private ones.
-
The disadvantage of this approach over first approach is race conditions. The reason we put the run method in the main application is so it can handle data in the main application. If the user starts more than one thread and they are simultaneously modifying the same shared data, then there are race conditions to worry about. Secondly, there is no constructor which makes it very hard to pass constructor arguments, thus each class starts off the same way.
-
Sample Code: The user implements runnable in the main class and the same class also has a bunch of other methods for making the task queue and calling the execute method.
The following is the approach 2 implementation of the counterexample explained in approach one:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MainAppRunnable implements Runnable {
private final int loopLimit;
private MainAppRunnable( int loopLimit)
{
this .loopLimit = loopLimit;
}
private void startThreads()
{
ExecutorService taskList
= Executors.newFixedThreadPool( 2 );
taskList.execute( this );
taskList.execute( this );
taskList.execute( this );
taskList.execute( this );
taskList.execute( this );
taskList.shutdown();
}
@Override
public void run()
{
for ( int i = 0 ; i < loopLimit; i++) {
System.out.println(
Thread.currentThread().getName()
+ " Counter: " + i);
}
pause(Math.random());
}
private void pause( double seconds)
{
try {
Thread
.sleep(Math.round(seconds * 1000.0 ));
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args)
{
new MainAppRunnable( 3 ).startThreads();
}
}
|
Output:
pool-1-thread-1 Counter: 0
pool-1-thread-2 Counter: 0
pool-1-thread-1 Counter: 1
pool-1-thread-1 Counter: 2
pool-1-thread-2 Counter: 1
pool-1-thread-2 Counter: 2
pool-1-thread-2 Counter: 0
pool-1-thread-2 Counter: 1
pool-1-thread-2 Counter: 2
pool-1-thread-2 Counter: 0
pool-1-thread-2 Counter: 1
pool-1-thread-2 Counter: 2
pool-1-thread-1 Counter: 0
pool-1-thread-1 Counter: 1
pool-1-thread-1 Counter: 2
Share your thoughts in the comments
Please Login to comment...