Implementing Threads in java
There are the following two ways to implements threads.
1. By extending Thread class
2. By implementing the Runnable interface and overwriting the run method.
Let’s look at both ways of implementing java threads through a code example.
1. By extending Thread Class
public class TestThread extends Thread{ public void run(){ System.out.println("Running in Thread"); } public static void main(String [] args){ TestThread testthread = new TestThread(); // Call start method to run thread and NOT run.// testthread.start(); } }2. By implementing the Runnable interface.
public class TestThread implements Runnable{ public TestThread(){ } public void doWork(){ //create instance of Thread and pass this class as argument. Thread worker = new Thread(this); worker.start(); } // overwrite run method public void run(){ System.out.println("Running in test Thread"); } public static void main(String [] args){ TestThread testthread = new TestThread(); testthread.doWork(); } }Thread Pool
The creation of a thread takes resources and time. In a server environment (Web or app server) where you can expect continuous requests for web pages, creating threads for each request and letting it die is a waste of CPU resources. In such environments, you can create a thread pool.Thread pool is a collection of pre-created threads that work on tasks when it available. If there is no task to finish, threads return to the pool and wait for the next request.
Example of Thread Pool
//Thread pool import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class ThreadPool { List<Task> taskList = new ArrayList<Task>(); List<WorkerThread> workers = new ArrayList<WorkerThread>(); boolean shutdown = false; public ThreadPool(int noOfThreads){ //add worker to connection pool for (int i=0; i <noOfThreads;i++){ WorkerThread workerThread =new WorkerThread("Worker: "+i ); workers.add(workerThread); workerThread.start(); } } public void putTaskForExecution(int numberOfTask){ synchronized(taskList){ for (int i =0;i <numberOfTask;i++){ taskList.add(new Task(i)); } //done adding all tasks, notify all waiting threads. taskList.notifyAll(); } } public void shutDown(){ shutdown = true; synchronized(taskList){ taskList.notifyAll(); } } class Task { int taskNo = 0; public Task(int taskNo) { this.taskNo = taskNo; } public void doTask(){ System.out.println(Thread.currentThread().getName() + " Finished task " +taskNo); } } private class WorkerThread extends Thread { public WorkerThread(String name){ super(name); } public void run(){ System.out.println("Starting thread "); while (!shutdown || !taskList.isEmpty() ){ try{ synchronized(taskList){ if (!taskList.isEmpty()){ Task myTask = taskList.remove(0); myTask.doTask(); }else { //no task to work on, wait for more work taskList.wait(); } //give other treads chance to work on tasks Thread.yield(); } }catch(Exception e){ e.printStackTrace(); } } System.out.println("Exiting thread " + this.getName()); } } public static void main(String [] args){ System.out.println("Starting thread server"); //create threads pool with 10 threds ThreadPool threadPool = new ThreadPool(10); //add task to thread pool and let it run threadPool.putTaskForExecution(100); System.out.println("Enter 1 to add more task and 0 exit"); Scanner sc = new Scanner(System.in); while(true){ int i = sc.nextInt(); if (i == 1){ threadPool.putTaskForExecution(100); }else if(i == 0 ){ threadPool.shutDown(); break; }else{ System.out.println("Invalid Input"); } System.out.println("Enter 1 to add more tasks and 0 exit"); } sc.close(); } }As creating pool and managing treads is a bit complex, in Java 5, we have ready-to-use classes which creates a pool of threads and manages those for you.
Let’s look at an example of creating a thread pool using Thread Executors.import java.util.ArrayList; import java.util.List; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ThreadPoolExe { final List <Task> taskList = new ArrayList<Task>(); final ExecutorService executor = Executors.newFixedThreadPool(5); Runnable active; ThreadPoolExe() { } public void finishWork(){ while(!taskList.isEmpty()){ Task task = taskList.remove(0); System.out.println("Working on task " + task.taskNo); executor.execute(task); } } public void putTaskForExecution(int numberOfTask){ for (int i =0;i <numberOfTask;i++){ taskList.add(new Task(i)); } } public void shutdown(){ executor.shutdown(); } private class Task implements Runnable { int taskNo = 0; public Task(int taskNo) { this.taskNo = taskNo; } public void run (){ System.out.println(Thread.currentThread().getName() + " Finished task:" +taskNo); try{ Thread.sleep(1000); }catch( Exception e){} } } public static void main(String [] args){ System.out.println("Starting thread server"); //create threads pool with 10 threds ThreadPoolExe threadPoolExe = new ThreadPoolExe(); //add task to thread pool and let it run threadPoolExe.putTaskForExecution(100); threadPoolExe.finishWork(); threadPoolExe.shutdown(); } }