方法的同步和異步


1. 方法的同步

同步處理
這種同步的方式處理,會發現,當這100此循環完成后,頁面才會返回 :同步,正在解析......。

  當后台在循環處理時,前台的頁面始終處於等待狀態。可以發現,使用都是一個線程在處理:

1.1 service

 /**
     * 同步方法
     */
    public void getTest1() {
        Users users = new Users();
        synchronized (users) {
            try {
                for (int i = 1; i <= 100; i++) {
                    log.info(Thread.currentThread().getName() + "----------同步:>" + i);
                    users.wait(200);
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }

1.2 controller

/**
     * 同步處理
     * 這種同步的方式處理,會發現,當這100此循環完成后,頁面才會返回 :同步,正在解析......。
     * 當后台在循環處理時,前台的頁面始終處於等待狀態。可以發現,使用都是一個線程在處理:
     * @return
     */
    @RequestMapping(value = "test1")
    public String test1(){
        loginService.getTest1();
        log.info(Thread.currentThread().getName()+"==========主線程名");
        return "同步,正在解析......";
    }

2. 方法的異步

2.1 異步處理1:

  實現:線程池,創建新線程處理

我們看控制台,會發現,主線程,和處理任務的線程,不是一個線程,也就是,當頁面請求后,主線程會返回我們想要返回的標識,
這里返回的是一個字符串:異步,正在解析......,而線程池新開了一個線程,在后台處理業務邏輯。
所以,此時訪問接口后,會立馬返回,頁面不用等待,處理邏輯在后台默默進行。

2.1.1 創建線程

package com.synchronize.RunnableTask;

import com.synchronize.model.Users;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class RunnableTask1 implements Runnable{
    private final Logger logger = LoggerFactory.getLogger(getClass());
  
    @Override  
    public void run(){
        Users users = new Users();
        synchronized (users){
            try {  
                for (int i = 1;i <= 100;i++){  
                    System.out.println(Thread.currentThread().getName()+"----------異步1:>"+i);
                    users.wait(200);
                }  
            }catch (Exception ex){  
                ex.printStackTrace();  
            }  
        }  
    }  
}  

2.1.2 controller

 /**
     * 異步處理1:線程池,創建新線程處理
     * 我們看控制台,會發現,主線程,和處理任務的線程,不是一個線程,也就是,當頁面請求后,主線程會返回我們想要返回的標識,
     * 這里返回的是一個字符串:異步,正在解析......,而線程池新開了一個線程,在后台處理業務邏輯。
     * 所以,此時訪問接口后,會立馬返回,頁面不用等待,處理邏輯在后台默默進行。
     * @return
     */
    @RequestMapping(value = "test2")
    public String test2(){
        ExecutorService service = Executors.newFixedThreadPool(5);
        RunnableTask1 task1 = new RunnableTask1();
        service.execute(task1);
        log.info("=========》當前線程名:"+Thread.currentThread().getName());
        return "異步1,正在解析......";
    }

2.2 異步處理2:

 實現:用springBoot自帶async注解

這種方式,是springBoot自身的一種異步方式,使用注解實現,非常方便,
我們在想要異步執行的方法上加上@Async注解,在controller上加上@EnableAsync,即可。
注意,這里的異步方法,只能在自身之外調用,在本類調用是無效的。

 2.2.1 service

 /**異步方法
     * 有@Async注解的方法,默認就是異步執行的,會在默認的線程池中執行,但是此方法不能在本類調用;
     * 啟動類需添加直接開啟異步執行@EnableAsync。
     * */
    @Async
    public String getTest2(){
        Users users = new Users();
        synchronized (users){
            try {
                for (int i = 1;i <= 100;i++){
                    log.info(Thread.currentThread().getName()+"----------異步2:>"+i);
                    users.wait(200);
                }
                return "執行異步任務完畢";
            }catch (Exception ex){
                ex.printStackTrace();
            }
        }
        return Thread.currentThread().getName()+"執行完畢";
    }

2.2.2 controller

package com.synchronize.controller;

import com.synchronize.RunnableTask.RunnableTask1;
import com.synchronize.service.LoginService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author luoxianwei
 * @date 2018/6/12
 */
@RestController
@Slf4j
@EnableAsync public class SynchronizedMethodController {

    @Autowired
    LoginService loginService;

    /**
     * 異步處理2:使用springBoot自帶async注解
     * 這種方式,是springBoot自身的一種異步方式,使用注解實現,非常方便,
     * 我們在想要異步執行的方法上加上@Async注解,在controller上加上@EnableAsync,即可。
     * 注意,這里的異步方法,只能在自身之外調用,在本類調用是無效的。
     */
    @RequestMapping(value = "test3")
    public String test3(){
        loginService.getTest2();
        log.info("============>"+Thread.currentThread().getName());
        return "異步2,正在解析......";
    }

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM