• 方法的同步和异步


    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,正在解析......";
        }
    
    }

  • 相关阅读:
    iscsi一致性的测试验证方法
    ceph各个版本之间参数变化分析
    rgw的rgw_thread_pool_size配置调整
    rgw前端替换civetweb为beast
    配置内网访问的TV
    关于vm.min_free_kbytes的合理设置推测
    rbd的删除回收站功能
    python爬取微博热门话题榜
    Selenium+Pytest自动化测试框架—禅道实战
    python带参数装饰器的两种写法
  • 原文地址:https://www.cnblogs.com/jcjssl/p/9437571.html
Copyright © 2020-2023  润新知