10086 customer service hotline understanding with advanced multi-threaded Java's thread pool


 Nietzsche said that humans can not understand what is not experienced. So many concepts can not be forced to understand and remember, you need to combine the case in real life.

Hotline Case

 For understanding the thread pool can be likened to the user to run the business of customer service calls, customer service operators assume a rest 500 people, the existing 500 users are one on one with the customer, then the first 501 users that is SpongeBob will hear voice waiting: "! hello rest now busy ..." SpongeBob can only wait, if more than 500 users have a hang up, SpongeBob can successfully connect to a live person;
 user phone calls to customer service for all is a task, and each customer can complete a number of tasks, rather than just 500 tasks, such as customer access to 100 calls per day, then the whole customer service background is completed 50,000 tasks;

Here Insert Picture Description

Analogy: where customer service can be seen as the background thread pool, 500 customer service can be seen as 500 threads, 500 users is Task, and the phone is turned on to perform this thing is the thread; user first 501 call the customer service hotline quite at 501 Task, more than the maximum thread can queue up, but they have to wait until another thread to complete before starting; This enables the reuse of the thread;

This analogy actual cases, can be found the following problems:

  • A thread is a valuable memory resources, a single thread accounting 1MB space. Easily lead to over-allocate memory overflow.
  • Frequent create and destroy threads will increase the overhead virtual machine recovery frequency resources, resulting in performance degradation program

The introduction of the thread pool

1. The concept of threads

The following is an excerpt from Baidu Encyclopedia

 Thread pool is a multithreaded processing forms processing tasks will be added to the queue, and then start these tasks automatically when a thread is created. Thread pool threads are background threads. Each thread uses the default stack size to default priority run, and in multi-threaded unit. If a thread in managed code is idle (eg is waiting for an event), then insert the thread pool thread to all other auxiliary processor to keep busy. If all thread pool threads are always busy, but the queue contains pending work, the thread pool creates another worker thread after a period of time but the number of threads will never exceed the maximum. More than the maximum thread can queue up, but they have to wait until another thread to complete before starting.

2. The role of the thread pool:

  • Tasks will be submitted to the thread pool. Allocated by the thread pool thread, run the task, and reuse the thread after the end of the current task.
  • Container threads. It can be set to limit the number of threads allocated.
  • The pre-created thread object into the pool, both with a thread pool thread object.
  • Avoid frequent creating and destroying threads.

Getting the Thread Pool

1. The common thread pool classes and interfaces

  • Executor: thread pool of top-level interface
method description
void execute(Runnable command) Executes the given command at some future time.
  • ExecutorService:
     thread pool interfaces, inherited the Executor, and increase and optimize the behavior of some parent interface, task code may be submitted by submit (Runnable task).
method description
Future submit(Callable task) The value returned submit tasks to perform, on behalf of the task and return pending results of Future.
Future<?> submit(Runnable task) Submit a runnable tasks performed, and returned saying that the future of the mission.
Future submit(Runnable task, T result) Submitted perform a task that can be run, and not a return that task
  • Executors factory class:

 It can be obtained by the following method a fixed number of threads of thread pool. The number of thread pool threads parameter that is

method description
static ExecutorService newFixedThreadPool(int nThreads) Create a thread pool, the thread pool thread to reuse a fixed number of runs from a shared unbounded queue.

Create a way

//线程池引用 ===> Executors工具类创建线程
        ExecutorService executorService = Executors.newFixedThreadPool(2);

 You can also newCachedThreadPool () Gets the number of dynamic thread pool, if not then automatically creates a new, no upper limit;

JavaApi:

Creates a thread pool that creates new threads as needed, but when available will reuse previously constructed threads. These pools will typically improve the execution of many short-lived asynchronous tasks of the program. Calls to execute will reuse previously constructed threads (if available). If no thread, a new thread is created and added to the pool. Not use a 60-second thread will be terminated and removed from the cache. Therefore, the pool will remain idle for a long time does not consume any resources. Please note, but you can create a pool (e.g., timeout parameters) of different details with similar properties using ThreadPoolExecutor constructor.

method description
static ExecutorService newCachedThreadPool() Creates a thread pool that creates new threads as needed, but when available will reuse previously constructed threads.

2. Code Case

 A current task, implement Runnable, print cycle 5 times, there is a cross-thread pool executorServiceto perform the task, respectively, and the maximum number of threads in the thread pool is 2;

public class TestThreadPool {
    public static void main(String[] args){

        //线程池引用 =  Executors工具类创建线程
        ExecutorService executorService = Executors.newFixedThreadPool(2);

        Runnable runnable = new MyTask();
        executorService.submit(runnable);
    }
}
class MyTask implements Runnable{

    @Override
    public void run() {
        for (int i = 0; i <5; i++) {
            System.out.println(Thread.currentThread().getName()+" MyTask: "+i);
        }
    }
}

Print result:
Here Insert Picture Description
If a task is submitted multiple times? For example, the task presented to the thread pool thread pool thread is greater than the maximum limit, you will
thread multiplexing happen?
Test Methods:

//线程池引用 =  Executors工具类创建线程
 ExecutorService executorService = Executors.newFixedThreadPool(2);
 Runnable runnable = new MyTask();
 executorService.submit(runnable);
 executorService.submit(runnable);
 executorService.submit(runnable);

 Apparently there are two threads has submitted three tasks, therefore, there must be a thread to be multiplexed.

Print result:
Here Insert Picture Description
 from the print results, the thread 1 is multiplexed twice, to avoid the frequent thread creation and destruction, to achieve the purpose of optimization;

Callable Interface

1. Concept Description

 Described in the foregoing Executortime, lists the following three methods, a method wherein the first parameter isCallable

method description
Future submit(Callable task) The value returned submit tasks to perform, on behalf of the task and return pending results of Future.
Future<?> submit(Runnable task) Submit a runnable tasks performed, and returned saying that the future of the mission.
Future submit(Runnable task, T result) Submitted perform a task that can be run, and not a return that task
@FunctionalInterface
public interface Callable<V>

 Returns a result and may lead to unusual task. Achieved by a method not define a single parameter called call.
Callable interface is similar to Runnable, because they are their class instance may be executed by another thread design. However, A Runnable does not return a result, you can not throw exceptions being examined.

2. scenarios

 If we need to calculate 1+2+3+......+1000000the results, a process that we need to deliver to multiple threads to execute, respectively, as Thread1before executing the 100,000 figures and, as Thread2 perform 100,000 to 200,000 sum of the numbers ... but which involves a problem that Thread1execution result of the execution has to return, or Thread2does not proceed according to the result of 1; obviously, can not be used at this time class implements Runnableinterfaces coverage runof the method to solve, because the return run is void;

class MyTask implements Runnable{
    @Override
    public void run() {
      //1+2+...+100000
    }
}

It uses Callableas its greatest feature is: return the results and may cause unusual task.
Here Insert Picture Description

3. Methods

method description
V call() Computing a result, if you can not do that, it will throw an exception.
  • JDK5 added, similar to the Runnable interface, after implementation represents a thread task.
  • Callable has a generic return value, you can declare exceptions.
public interface Callable<V>{
	public V call() throw Exception;
}

4. The application of the method

public class TestCallable {
    public static void main(String[] args){
        //创建线程池
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        Callable task = new Task();
        executorService.submit(task);
        executorService.submit(task);
        executorService.submit(task);
    }
}
class Task implements Callable<String>{
    @Override
    public String call() throws Exception {
        for (int i = 0; i <5 ; i++) {
            System.out.println(Thread.currentThread().getName()+" : "+i);
        }
        return null;
    }
}

Print result:
Here Insert Picture Description
 Clearly there are two threads has submitted three tasks, therefore, thread 2 multiplexes.

Future interfaces

1. introduction

& emsp; we will begin to introduce the case: the calculation 1+2+3+......+1000000result of this process we need to deliver to multiple threads to execute respectively, Callable can return type, but how will a sum of the various threads of the return type it? Future interface need to introduce here, the object which encapsulates call()the return value

JavaApi:

Results A Future calculations. Provides a method to check the computation is complete, waiting for its completion, and retrieves the results. The results can only be used after the calculation method get retrieved, if necessary, block until ready. Cancel performed by the cancel method. Provide another way to determine whether a task is completed normally or canceled. After completion of the calculation, calculation can not be canceled. If you want to use Future, so irrevocably, but does not provide a usable result, you can declare Future <?> Type table and returns null as the basis of the results of the task.

2. Methods

method description
boolean cancel(boolean mayInterruptIfRunning) Attempt to cancel the execution of this task.
V get() Wait calculations are complete, and then retrieves the result.
V get(long timeout, TimeUnit unit) If you need to wait for a given time to complete the calculation of a maximum, and then retrieves the result (if available).
boolean isCancelled() If this task was canceled before it completed normally, it returns true.
boolean isDone() Returns true if this task completed.

3. Solve the problem of sub-tasks performed 1 + 2 + ... + 100

public class TestCallable {
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		System.out.println("程序开始");
		//创建线程池
		ExecutorService es = Executors.newFixedThreadPool(3);
		
		Callable<Integer> task1 = new MyTask1();
		Callable<Integer> task2 = new MyTask2();
		//接收两个任务的返回值
		Future<Integer> f1 = es.submit(task1);
		Future<Integer> f2 = es.submit(task2);
		//检索计算结果并返回给变量
		Integer result1 = f1.get();//无限期等待
		Integer result2 = f2.get();//无限期等待
		//输出结果
		System.out.println("result1:"+result1 + " + result2:"+result2 +" = " +(result1+result2));		
	}
}
//线程1计算1+2+....+50
class MyTask1 implements Callable<Integer>{
	@Override
	public Integer call() throws Exception {
	  	Thread.sleep(5000);
		Integer sum = 0;
		for (int i = 1; i <= 50; i++) {
			sum += i;
		}
		return sum;
	}
}
//线程2计算51—+52+.....+100
class MyTask2 implements Callable<Integer>{
	@Override
	public Integer call() throws Exception {
	    Thread.sleep(5000);
		Integer sum = 0;
		for (int i = 51; i <= 100; i++) {
			sum += i;
		}
		return sum;
	}
}

Print results (this is a motion picture):
Here Insert Picture Description
 From the printing results, V get()is blocked in the form of waiting Future asynchronous (multi-threaded) processing result ( call()return value); popular, here let two threads to sleep for five second, so in the course of two threads in the waiting period, V get()is blocked in the form of waiting threads is finished, after in order to get Futurethe return value;


 In fact, there has been very close friends - feel distributed
Here Insert Picture Description

Published 85 original articles · won praise 196 · views 130 000 +

Guess you like

Origin blog.csdn.net/qq_44717317/article/details/104928731