Multithreaded thread pool

There are several implementations of multithreading, which are they?

a, inherit the Thread class

b. Implementing Runnable Interface

c. Implementing Callable Interface through Thread Pool

 

Thread pool, in fact, is a container containing multiple threads, in which threads can be used repeatedly, eliminating the operation of creating thread objects frequently, and consuming too much resources without creating threads repeatedly.

Let's explain in detail why thread pools are used.

In java, if each request arrives, a new thread is created, which is quite expensive. In practical use, creating and destroying threads takes considerable time and consumes much more system resources than actually processing user requests. In addition to the overhead of creating and destroying threads, active threads also consume system resources. If too many threads are created in a jvm, the system may be under-resourced due to excessive memory consumption or "over-switching". In order to prevent resource shortage, some methods are needed to limit the number of requests processed at any given time, to minimize the number of threads created and destroyed, especially those threads that consume more resources, and to make the best use of existing objects for services.

Thread pool is mainly used to solve the problem of thread lifecycle overhead and resource shortage. By reusing threads for multiple tasks, the overhead of thread creation is allocated to multiple tasks, and because threads already exist when requests arrive, the delay caused by thread creation is eliminated. In this way, the request can be served immediately and the application can respond faster. In addition, by properly adjusting the number of threads in a thread, we can prevent resource shortage.

Reasonable use of thread pools can bring three benefits:

1. Reduce resource consumption. It reduces the number of threads created and destroyed, and each worker thread can be reused to perform multiple tasks.

2. Improving the response speed. When a task arrives, it can be executed immediately without waiting for the thread to be created.

3. Improve the manageability of threads. According to the system's endurance, the number of workline threads in the thread pool can be adjusted to prevent the server from accumulating because of excessive memory consumption (each thread needs about 1MB of memory, the more threads open, the more memory consumed, and the last crash).

 

The top-level interface of thread pool in Java is java.util.concurrent.Executor, but strictly speaking, Executor is not a thread pool, but a tool to execute threads. The real thread pool interface is java.util.concurrent.ExecutorService.

To configure a thread pool is complex, especially when the principle of thread pool is not clear, it is possible to configure a thread pool is not optimal, so some static factories are provided in the java.util.concurrent.Executors thread factory class to generate some commonly used thread pools. The official recommendation is to use the Executors engineering class to create thread pool objects.

In the Executors class, there is a way to create a thread pool as follows:

Public static ExecutorService new Fixed ThreadPool (int nThreads): Returns the thread pool object. (A bounded thread pool is created, i.e. the maximum number of threads in the pool can be specified)

Get a thread pool ExecutorService object, then how to use it, here defines a method of using thread pool object as follows:

Public Future<?> submit (Runnable task): Gets a thread object in the thread pool and executes it

Future interface: Used to record the results of a thread task after execution. Thread pool creation and use.

Steps to use thread objects in thread pools:

Create thread pool objects.

Create Runnable interface subclass objects. (task)

Submit Runnable interface subclass objects. (take task)

Close the thread pool (usually not).

 

Runnable implements class code:

public class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("I want a coach.");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Here comes the coach. " + Thread.currentThread().getName());
        System.out.println("Teach me to swim,After handing it in, the coach returned to the swimming pool.");
    }
}

Thread pool test class:

public class ThreadPoolDemo {
    public static void main(String[] args) {
        // Create thread pool objects
        ExecutorService service = Executors.newFixedThreadPool(2);//Contains two threaded objects
        // Create Runnable instance objects
        MyRunnable r = new MyRunnable();
​
        //How to Create Thread Objects by Yourself
        // Thread t = new Thread(r);
        // T. start (); - > Call run() in MyRunnable
​
        // Get the thread object from the thread pool and call run() in MyRunnable
        service.submit(r);
        // Get another thread object and call run() in MyRunnable
        service.submit(r);
        service.submit(r);
        // Note: After the submit method call, the program does not terminate because the thread pool controls the closure of the thread.
        // Return the used thread back to the thread pool
        // Close thread pool
        //service.shutdown();
    }
}

Using Thread Pool--Runnable Interface

Typically, thread pools are created through thread pool factories, which call methods in the thread pool to get threads, and then execute task methods through threads.

  1. Executors: Thread pool creation factory class
    1. Public static Executor Service new Fixed ThreadPool (int nThreads): Returns the thread pool object
  2. ExecutorService: Thread pool class
    1. Future<?> submit (Runnable task): Get a thread object in the thread pool and execute it
  3. Future interface: Used to record the results of a thread task after execution. Thread pool creation and use

 

  1. Steps to use thread objects in thread pools:
    1. Create thread pool objects
    2. Creating Runnable Interface Subclass Objects
    3. Submitting Runnable Interface Subclass Objects
    4. Close thread pool

Code demonstration:

public class ThreadPoolDemo {
	public static void main(String[] args) {
		// Create thread pool objects
		ExecutorService service = Executors.newFixedThreadPool(2);//Contains two threaded objects
		// Create Runnable instance objects
		MyRunnable r = new MyRunnable();
		
		// How to Create Thread Objects by Yourself
		//Thread t = new Thread(r);
		//T. start (); - > Call run() in MyRunnable
		
		// Get the thread object from the thread pool and call run() in MyRunnable
		service.submit(r);
		// Get another thread object and call run() in MyRunnable
		service.submit(r);
		service.submit(r);
        // Note: After the submit method call, the program does not terminate because the thread pool controls the closure of the thread. Return the used thread back to the thread pool

        // Close thread pool
		//service.shutdown();
	}
}

Runnable interface implementation class:

public class MyRunnable implements Runnable {
	@Override
	public void run() {
		System.out.println("I want a coach.");
		
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("Here comes the coach. " +Thread.currentThread().getName());
		System.out.println("Teach me to swim,After handing it in, the coach returned to the swimming pool.");
	}
}

Using Thread Pool - Callable Interface

  1. Callable interface: Similar to the Runnable interface, it is used to specify tasks for threads. The call() method is used to return the result after the thread task has been executed, and the call method throws an exception.
  2. ExecutorService: Thread pool class
    1. Future < T > submit (Callable < T > task): Get a thread object in the thread pool and execute the call() method in the thread
  3. Future interface: Used to record the results of a thread task after execution. Thread pool creation and use
  4. Steps to use thread objects in thread pools:
    1. Create thread pool objects
    2. Creating Callable Interface Subclass Objects
    3. Submit Callable Interface Subclass Objects
    4. Close thread pool

Code demonstration:

public class ThreadPoolDemo {
	public static void main(String[] args) {
		//Create thread pool objects
		ExecutorService service = Executors.newFixedThreadPool(2);//Contains two threaded objects
		//Create Callable Objects
		MyCallable c = new MyCallable();
		
		//Get the thread object from the thread pool and call run() in MyRunnable
		service.submit(c);
		
		//Get another coach
		service.submit(c);
		service.submit(c);
        //Note: After the submit method call, the program does not terminate because the thread pool controls the closure of the thread. Return the used thread back to the thread pool

        //Close thread pool
		//service.shutdown();
	}
}

Callable interface implementation class, call method can throw exceptions and return the results after the thread task has been executed:

public class MyCallable implements Callable {
	@Override
	public Object call() throws Exception {
		System.out.println("I want a coach.:call");
		Thread.sleep(2000);
		System.out.println("Here comes the coach. " +Thread.currentThread().getName());
		System.out.println("Teach me to swim,After delivery,The coach returned to the swimming pool.");
		return null;
	}
}

Thread pool exercise: Returns the result of adding two numbers

Requirements: Through the thread object in the thread pool, the Callable interface is used to complete the sum of two numbers.

  1. Future interface: Used to record the results of a thread task after execution. Thread pool creation and use
    1. V get() Gets the encapsulated data results in the Future object

Code demonstration:

public class ThreadPoolDemo {
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		//Create thread pool objects
		ExecutorService threadPool = Executors.newFixedThreadPool(2);
		
		//Create a Callable interface subclass object
		//MyCallable c = new MyCallable();
		MyCallable c = new MyCallable(100, 200);
		MyCallable c2 = new MyCallable(10, 20);
		
		//Get the thread in the thread pool and call() method in the Callable interface subclass object to complete the summation operation.
		//<Integer> Future<Integer> submit(Callable<Integer> task)
		// Future result object
		Future<Integer> result = threadPool.submit(c);
		//The type of result returned by the get method of this Future
		Integer sum = result.get();
		System.out.println("sum=" + sum);
		
		//Demonstration again
		result = threadPool.submit(c2);
		sum = result.get();
		System.out.println("sum=" + sum);
		//Close the thread pool (you can not close it)
		
	}
}

Callable interface implementation class:

public class MyCallable implements Callable<Integer> {
	//Membership variables
	int x = 5;
	int y = 3;
	//Construction method
	public MyCallable(){
	}
	public MyCallable(int x, int y){
		this.x = x;
		this.y = y;
	}

	@Override
	public Integer call() throws Exception {
		return x+y;
	}
}

Keywords: Java jvm

Added by BlueKai on Sat, 20 Jul 2019 06:33:27 +0300