Markdown Editor on the line, and finally wait for you! Using this editor to write two articles, it feels good! But there are some problems, slowly familiar with it!
Actuator
There is a cost to building a new thread because it involves interacting with the operating system. If you create a large number of threads in your program that have short life cycles, you should use the thread pool.
Another reason to use the thread pool is to reduce the number of concurrent threads. Too many threads can greatly degrade performance and even crash the virtual machine. If you have an algorithm that creates many threads, you should use a "fixed" thread pool of threads to limit the total number of concurrent threads.
static method of building thread pool for executor class
Method |
Description |
Newcachedthreadpool |
Creates a new thread if necessary, and the idle thread is retained for 60 seconds |
Newfixedthreadpool |
The pool contains a fixed number of threads, and idle threads are kept |
Newsinglethreadexecutor |
Only one thread of the "pool", the thread that executes each submitted task sequentially |
Newscheduledthreadpool |
Fixed thread pool built for scheduled execution, instead of Java.util.Timer |
Newsinglethreadscheduledexecutor |
Single-threaded "pool" Built for scheduled execution |
thread Pool
The Newcachedthreadpool method constructs a thread pool, and for each task, if an idle thread is available, let it perform the task immediately, and if there is no free thread available, create a new thread.
The Newfixedthreadpool method constructs a thread pool with a fixed size. If the number of tasks submitted is more than the number of idle threads, then the tasks of the service that are not available are placed in the queue. Run them again when other tasks are completed.
Newsinglethreadexecutor is a degraded thread pool of size 1: One thread executes the submitted task, and then one after the other. These three methods return objects of the Threadpoolexecutor class that implement the Executorservice interface.
Using connection pooling:
- Call the static method Newcachedthreadpool or Newfixedthreadpool in the Executors class.
- Call submit to submit the Runnable or callable object.
- If you want to cancel a task, or if you commit a callable object, save the returned future object.
- When no tasks are committed, call shutdown.
Macthcounter class:
/** * @author Xzzhao * * Public class macthcounter implements callable<Integer> { Private FinalFile directory;Private FinalString keyword;Private FinalExecutorservice Pool;Private int Count; PublicMacthcounter (File directory, String keyword, executorservice pool) {Super(); This. directory = Directory; This. keyword = keyword; This. pool = Pool; } @Override PublicInteger call () throws Exception {Count=0; file[] files = directory.listfiles (); list<future<integer>> results =NewArraylist<> (); for(File file:files) {if(File.isdirectory ()) {Macthcounter counter =NewMacthcounter (file, keyword, pool); futuretask<integer> task =NewFuturetask<> (counter); Results.add (Task); }Else{if(Search (file)) {Count++; } } } for(future<integer> result:results) {Count+ = Result.get (); }return Count; }/** * Search Method * * @param file * @return found * * Public BooleanSearch (file file) {Try{Try(Scanner in =NewScanner (file)) {BooleanFound =false; while(!found && in.hasnextline ()) {String line = In.nextline ();if(line.contains (keyword)) {found =true; } }returnFound } }Catch(Exception e) {E.printstacktrace (); }return false; }}
Threadpooltest class:
/** * @author Xzzhao * * Public classthreadpooltest { Public Static void Main(string[] args) {Scannerinch=NewScanner (System.inch); System. out. println ("Please enter the root directory:"); String directory =inch. nextline (); System. out. println ("Please enter the keyword:"); String keyword =inch. nextline (); Executorservice pool = Executors.newcachedthreadpool (); Macthcounter counter =NewMacthcounter (NewFile (directory), keyword, pool); future<integer> result = Pool.submit (counter);Try{System. out. println ("Number of documents to match:"+ result.Get()); }Catch(Interruptedexception e) {E.printstacktrace (); }Catch(Executionexception e) {E.printstacktrace (); } pool.shutdown ();intLargestpoolsize = ((threadpoolexecutor) pool). Getlargestpoolsize (); System. out. println ("Largestpoolsize="+ largestpoolsize); }}
Scheduled Execution
The Scheduledexecutorservice interface has a method that is designed for scheduled execution or repetitive execution of tasks. It is a generalization of a Java.util.Timer that allows the threading mechanism to be used. The Newscheduledthreadpool and Newsinglethreadscheduledexecutor methods of the Executors class return the object that implements the Scheduledexecutorservice interface.
You can schedule runnable or callable to run only once after the initial delay. You can also schedule a Runnable object to run periodically.
Control task Groups
We already know how to use an executor service as a thread pool to improve the efficiency of performing tasks. Sometimes we use actuators to do something more practical, to control a set of related tasks. For example, you can use the Shutdownnow method in the executor to cancel all tasks.
The InvokeAll method submits all objects to a collection of callable objects and returns a list of future objects that represent the results of all tasks. The disadvantage of this approach is that if the first task takes a lot of time, you may have to wait. It is more meaningful to save the results in the order in which they are obtained. You can use Executorcomeletionservice to sort them.
The API can be queried specifically. Obtain an actuator in the usual way. Then, build a executorcomeletionservice and submit the task to complete the service. The service manages the blocking queue for the future object, which contains the execution results of the tasks that have been submitted.
Probably as follows:
Executors.newCachedThreadPool();ExecutorCompletionService service = new ExecutorCompletionService<>(executor);for{ service.submit(task);}fori0itask.sizei{ processFurther(service.take().get());}
Fork-join Frame
Some applications use a large number of threads, but most of them are idle. For example, a Web server might use one thread for each connection. Other applications may use a single thread for each processor core to perform computationally intensive tasks, like or video processing. The Fork-join framework was introduced in Java SE 7 to support the latter class of applications.
Let's discuss a simple example. Suppose we want to count how many elements in an array satisfy a particular property. This array can be divided into two parts, respectively, and then add the results.
Counter class:
/** * @author Xzzhao * * Public classCounter extends Recursivetask<integer> { Public StaticFinalintTHRESHOLD = +;PrivateFinalDouble[] values;PrivateFinalint from;PrivateFinalintto;PrivateFinal filter filter; Public Counter(Double[] values,int from,intTo, filter filter) {super (); This. values = values; This. from= from; This. to = to; This. filter = filter; } @OverrideprotectedIntegerCompute() {if(To- from< THRESHOLD) {intCount =0; for(inti = from; I < to; i++) {if(Filter.accept (Values[i])) {count++; } }returnCount }Else{intMid = (( from+ to)/2); Counter first =NewCounter (values, from, Mid, filter); Counter second =NewCounter (values, mid, to, filter); InvokeAll (first, second);returnFirst.Join() + second.Join(); } }}
Counter class:
/** * @author Xzzhao * * Public class forkjointest { Public Static void Main(string[] args) {Final intSIZE =10000000;Double[] numbers =New Double[SIZE]; for(inti =0; i < SIZE; i++) {Numbers[i] = Math.random (); } Counter Counter =NewCounter (Numbers,0, Numbers.length,NewFilter () {@Override Public Boolean Accept(Doublex) {returnX >0.5; } }); Forkjoinpool pool =NewForkjoinpool (); Pool.invoke (counter); System.out.println (Counter.join ()); }}
This recursive calculation is done in a way that the framework is available, requiring a class that extends the Recursivetask, if the calculation produces a result, or if no result is generated, you can provide a class that extends the recursiveaction. Then overwrite the compute method to generate and invoke the child task, and then merge the results.
The InvokeAll method receives many tasks and blocks, knowing that all of these tasks have been completed. The Join method produces the result. A join is applied to each subtask and the sum is returned.
Java Multithreading--actuators (Executor)