I. Completablefuture
1.Future Interface
The purpose of the future design is to model the results that will occur at some point in time.
It models an asynchronous computation that returns a reference to the result of the execution of the operation, which is returned to the caller when the operation is finished. Starting in the future those potentially time-consuming operations freed up the calling thread so that it could continue to perform other valuable work, no longer having to wait for time-consuming operations to complete.
The advantage of the future: easier to use than the lower thread.
To use the future, you typically only need to encapsulate the time-consuming action in a callable object, and then submit it to Executorservice.
Executorservice executor = executors.newcachedthreadpool (); Future<double> future = executor.submit (new callable<double> () { // Submit a Callable Object @Override to Executorservice public double call () throws Exception { return Dosomelongcomputation (); //asynchronously executes time-consuming operations in a new thread } }); Dosomethingelse (); //asynchronous operation, you can do other things try { //get the result of the asynchronous operation, if it is eventually blocked, cannot get the result, Then Exit double result = future.get (1, timeunit.seconds) after waiting for up to 1 seconds;} catch (Executionexception ee) { //plus throws an exception} catch ( Interruptedexception ie) { //The current thread is interrupted during the wait} catch (TimeoutException te) { //exceeds expired before the future object is completed}
2. Implement asynchronous APIs, code to avoid blocking
Create Completablefuture using the factory method Supplyasync
Public future<double> GETPRICEASYNC2 (String product) {return Completablefuture.supplyasync (() Calculatepr Ice (product));}
The Supplyasync method takes a producer (Supplier) as a parameter and returns a Completablefuture object that reads the return value of the calling producer method when the object finishes executing asynchronously.
The Producer method is run by an execution thread (Executor) in the Forkjoinpool pool, but you can also use the overloaded version of the Supplyasync method, passing the second parameter to specify a different execution thread to execute the producer method.
Join method waits for asynchronous operation to end
The Join method in the Completablefuture class has the same meaning as get in the future interface, and waits for the end of the run. Also declared in the future interface, the only difference is that the join method does not throw any detected exceptions. Therefore, it is not necessary to use the Try/catch statement block when using it.
Public list<string> findprices (String product) {//uses completablefuture to asynchronously calculate the price of each commodity list<completablefuture <String>> pricefutures = Shops.stream (). Map (Shop-Completablefuture.supplyasync (), Shop.getname () + "Price is" + shop.getpriceasync (product)). Collect (Collectors.tolist ());//waits for all asynchronous operations to end with return Pricefutures.stream (). Map (Completablefuture::join). Collect (Collectors.tolist ());}
Using Custom Actuators
Create an executor with a thread pool.
Select the number of threads: N (threads) = N (CPU) * U (CPU) * (1 + w/c)
--N (CPU): The number of cores of the processor that can be obtained by Runtime.getruntime (). Availableprocessors ();
--U (CPU): Expected CPU utilization (the value should be between 0 and 1);
--w/c: The ratio of the wait time to the calculated time.
To create a thread pool, the number of threads in the threading pools is 100 and the store number is the smaller of the values (here 100 is the upper limit of the thread pool) Private final Executor Executor = Executors.newfixedthreadpool ( Math.min (Shops.size (), +), new Threadfactory () {@Overridepublic thread newthread (Runnable r) {Thread t = new Thread (r); t . Setdaemon (True); Use daemon thread-this way does not prevent the program from shutting down return t;});
There are two ways in which collections perform parallel computations: parallel streams and completablefutures.
--computationally intensive and without I/O, it is recommended to use the stream interface. Because the implementation is simple, and the efficiency is probably the highest (if all the threads are computationally intensive, there is no need to create more threads than the number of processor cores);
--If parallel work units also involve operations that wait for I/O, including network connection waits, then using completablefuture is more flexible. In this case, if I/O waits occur in the pipeline that processes the flow, the latency characteristics of the stream can make it difficult to determine when the wait is triggered.
3. Pipeline operations on multiple asynchronous tasks
thenapply: Pass a method of string conversion Quote to him as a parameter
&NBSP, thencompose: Span style= "LINE-HEIGHT:1.57143EM; font-size:10pt; " > This method allows you to pipeline two asynchronous operations, and when the first operation completes, it passes the result as a parameter to the second operation.
invokes Thencompose on the first Completablefuture object and passes a function to it. when the first completablefuture is executed, his result will be the parameter of the function, and the return value of the function is the first completablefuture Returns the second Completablefuture object that was computed as input .
Use Thencompose to reduce the overhead of many thread switching.
thencombine: integrates the results of two Completablefuture objects. The method receives a second parameter named Bifunction, which defines how the two Completablefuture objects are merged after the calculation is completed.
thenaccept: method Receives completablefuture after execution, the return value is the parameter. You do not have to wait for those results that have not yet returned.
New features of Java8: Completablefuture