Create a thread pool
/** Thread pool * */ Private Static Final Executorservice pool = Executors.newfixedthreadpool (thread_size);
/**
The thread pool has a variety of preset templates that you can use directly if you are unfamiliar with Fixedthreadpool.
The number of threads is limited according to the length passed in later. The exceeded task will wait.
**/
The exact size calculation method:
CPU-intensive: CPU Core number +1 (if the CPU itself is not strong, it is recommended not to +1, such as a dual-core CPU)
i/0, Network intensive: Number of CPU Cores * 2 +1 (Network request if it's slow, you can get a little higher.) If it is the same machine Io, personally think is still counted as intensive, because the main bottleneck in IO)
It mainly introduces two kinds, one is not return runnable, the other is the future with return
Both methods use an inverted lock for the end of the thread
Size is the number of tasks
New Countdownlatch (SIZE);
Runnable
FinalCountdownlatch latch =NewCountdownlatch (SIZE); Pool.execute (NewRunnable () {@Override Public voidrun () {Try { // Do}Catch(Exception e) {//Error}finally{latch.countdown (); } } }); Latch.await ();
If you use Runnabledirectly, the passed-in parameters need to be final. So you can create a new Runnable class so that you only need to pass in a normal Java object
New Countdownlatch (SIZE); Pool.execute (new Saveworker (Id,latch)); Latch.await ();
Saveworker Class
Private Final classSavetaskImplementsRunnable {PrivateString ID; PrivateCountdownlatch latch; PublicSavetask (String ID, countdownlatch latch) { This. ID =ID; This. Latch =latch; } @Override Public voidrun () {Try{logger.info ("Incoming ID is {}", id); } Catch(Exception e) {logger.error ("Exception occurred: {}", E.getmessage (), E); } finally{latch.countdown ();//counter minus one } } }
Attention:
1. The exception in the thread can no longer be thrown outside, so it should be printed or processed in the threads.
2. There is a limit between threads, do not pass in too large objects.
3. For additions and deletions of the operation. To use a thread-safe container, the object is processed.
Future
1, set to ensure thread safety, the inside will use the lock, so that the CPU in the implementation of the lock-related operations will be in the "User state" and "kernel State" switch, because from the user state to access the kernel state needs to do extra work, it will increase the cost of access; Concepts and objects such as locks are the instructions in the kernel, and the OS simply encapsulates them and opens interfaces to the upper program.
2, when the multi-threaded to compete for the lock, no competition to lock the use of the thread will be blocked and wait to be awakened and then go to the competition to know the use of the lock. In this process, when a thread is blocked, it increases the overhead of CPU execution context switching, and the CPU usage is not high. (because the CPU is constantly polling for checks, the blocked threads are suspended and the threads in a running state get the CPU's right to use)
The callable interface in the JUC package can be used to solve this problem. When you put a task into the thread pool, the thread pool returns a future object that is saved (this process is synchronous, not asynchronous.) So you can use a thread-unsafe class to improve performance, and when the worker thread finishes executing it will save the results in the future object, and then you can get the returned results from them and do the subsequent processing.
If you use Runnable, you will use the thread-safe classes in the Concurrency tool class to handle it. Only normal LinkedList (thread insecure) is required here.
Result set
list<map<string, object>> maplist =NewLinkedlist<>(); Try { intTotalCount =GetCount ();//method of obtaining the total number of pages; intPages = (int) Math.ceil (TotalCount/(Double) pageSize); Calculate the number of pages List<future<list<map<string, object>>>> futures =NewArraylist<>(pages); Countdownlatch latch=NewCountdownlatch (pages); Future<list<map<string, object>>> res =NULL; for(inti = 0; i < pages; i++) {
Returns the result added to the list res= Executor.submit (NewGettask (latch, i)); Futures.add (RES); } latch.await ();
Iterate through the list and add it to the result set that we really returned. for(Future<list<map<string, object>>>future:futures) {Maplist.addall (Future.get ()); } } Catch(Exception e) {logger.error ("Multithreading-paging gets excluded customers, error occurred:", e); }
return maplist;
The implementation of the class is similar to the above, only need to implement a return interface
Private Final classGettaskImplements Callable<list<map<string, object>>> {
Private Countdownlatch latch;
private int page;
Public Geteliminatecustomertask (countdownlatch latch, int page) {
This.latch = latch;
this.page = page;
}
@Override
Public list<map<string, Object>> call () throws Exception {
try {
int start = page * pageSize;
Return Seachbypage (start,pagesize); Paging Get Data
} catch (Exception e) {
Logger.error ("Get section". Concat (String.valueof (page+1). Concat ("page data Error"), e);
} finally {
Latch.countdown ();
}
return null;
}
}
Multithreading calls demo-thread pool