Java Run Multiple Tasks Simultaneously

Sometimes we may need to write a program that can process multiple tasks concurrently. Java supports multithreading which means that we can run multiple threads to do different task at the same time within a single program.

In this example, we will use Java built-in ExecutorService from the java.util.concurrent package to execute multiple tasks asynchronously.

Here's an example code that demonstrates running of 1000 tasks concurrently at one time:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class Example {

   public static void main(String[] args) {
	// 50000 tasks
	List tasks = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 50000);

	// task start time
	long startTime = System.currentTimeMillis();


	// task end time
	long endTime = System.currentTimeMillis();
	double timeTaken = (endTime - startTime) / 1000;

	System.out.println("Time taken to run " + tasks.size() + " urls = " + timeTaken + " seconds");


   public static void initiateRequest(List tasks) {

	if (tasks.isEmpty()) {

	int numberOfThreads = 1000;
	ExecutorService fixedPoolExecutor = Executors.newFixedThreadPool(numberOfThreads);

	List> futureList = new ArrayList<>();
	tasks.forEach(url -> {
	    Future future = fixedPoolExecutor.submit(() -> myTask(url));

	for (Future future : futureList) {
	    try {
		 System.out.println("Response received = " + future.get());
	    } catch (InterruptedException | ExecutionException e) {

   private static String myTask(int taskId) {
	System.out.println("Started task ID : " + taskId);
	try {
	} catch (InterruptedException e) {

	System.out.println("Completed task ID : " + taskId);
	return "Task ID : " + taskId;

The example code starts by importing necessary classes from the Java API. A class called "Example" is defined, which contains a main method as the entry point of the program. In the main method, a list of tasks is created using the Arrays.asList() method. Each task is represented by a number.The start time of the tasks is recorded using System.currentTimeMillis(). The initiateRequest method is called, passing the list of tasks as an argument. If the list is empty, the method returns early. The numberOfThreads variable is set to 1000, indicating the maximum number of tasks that can run concurrently. An ExecutorService is created using Executors.newFixedThreadPool(numberOfThreads), which creates a pool of threads to execute the tasks. A list called "futureList" is created to store the results of the tasks. The forEach method is used to iterate over each task in the list and submit it to the ExecutorService using the submit() method. The resulting Future object is added to the futureList. A loop is used to iterate over the futureList. For each Future object, the get() method is called to retrieve the result of the corresponding task. This is a blocking operation, meaning it waits until the task completes and returns a result. The retrieved result is printed to the console. After all tasks are completed, the ExecutorService is shut down to release the allocated resources. The completion time of the tasks is recorded using System.currentTimeMillis(), and the elapsed time is calculated in seconds. Finally, the total time taken and the number of tasks completed are printed to the console.

In summary, the code demonstrates how to run multiple tasks concurrently using an ExecutorService and retrieve the results of the tasks as they complete. The tasks are executed by a pool of threads, allowing for efficient parallel processing.