Business Scenario: The front end requests the back end, which performs a series of operations and then returns the results to the front end, during which time the front end has been in a loading wait state.In some cases, we may not have to wait for some of the businesses (such as complex log operations, remote calls, etc.) but they are time-consuming and can be called asynchronously using multiple threads.
Gossip without sticking code:
Requested Controlle Layer
@RequestMapping("/hello") @ResponseBody public Boolean hello(){ customerTagService.hello(1); return true; }
Service Layer
public void hello(Integer index){ try { System.out.println(index); Thread.sleep(6000); } catch (InterruptedException e) { e.printStackTrace(); } }
The above Write Front End page waits for 6s before returning results.
Modify the Service layer code
public void hello(Integer index){ ExecutorService executor = Executors.newCachedThreadPool(); executor.execute(new Runnable() { @Override public void run(){ // Write time-consuming task code from here System.out.println(index); try { Thread.sleep(6000); } catch (InterruptedException e) { e.printStackTrace(); } } }); }
perhaps
It is also possible to modify the invocation method of the Control layer if you do not want or cannot change the Service layer
@RequestMapping("/hello") @ResponseBody public Boolean hello(){ ExecutorService executor = Executors.newSingleThreadExecutor(); executor.execute(new Runnable() { @Override public void run(){ customerTagService.hello(1); } }); return true; }
Modified front-end pages only need to wait less than 1s
This is where we originally wanted to be.
----------------------------
extend
This is where you actually create a thread pool using Executor to put the created thread tasks to execute.
Notice that newCachedThreadPool is used here, so let's modify the Service:
public void hello(Integer index){ ExecutorService executor = Executors.newCachedThreadPool(); for (int i = 0; i < 5; i++) { final int ii = i; executor.execute(new Runnable() { @Override public void run(){ System.out.println(DateUtil.getCurrDateTime()+"thread-"+ii+"-:start"); try { Thread.sleep(6000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(DateUtil.getCurrDateTime()+"thread-"+ii+"-:End"); } }); } }
There is one more loop, adding five threads to the thread pool, and the front-end wait time does not change much.
rear output
Five threads execute simultaneously, and five threads execute for a total of 6s.
Let's change the Service to newSingleThreadExecutor with newCachedThreadPool
public void hello(Integer index){ ExecutorService executor = Executors.newSingleThreadExecutor(); for (int i = 0; i < 5; i++) { final int ii = i; executor.execute(new Runnable() { @Override public void run(){ System.out.println(DateUtil.getCurrDateTime()+"thread-"+ii+"-:start"); try { Thread.sleep(6000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(DateUtil.getCurrDateTime()+"thread-"+ii+"-:End"); } }); } }
The front end is still less than 1s old
rear output
Here, five threads execute sequentially, six seconds per thread, and five threads are completed in 30s.(Note that this is for one access only, multiple access does not execute threads in the order in which they are accessed)
This is a difference between newCachedThreadPool and newSingleThreadExecutor, with four total thread pools including newFixedThreadPool and newScheduledThreadPool.Specific differences are described on the Internet, where only the places I use are written.
There are many specific writings, only one of which is listed here, as well as new Thread () and new Callable () with a return value.
Please correct any mistakes.