精华内容
下载资源
问答
  • 多线程异步处理数据
    千次阅读
    2021-02-27 14:40:17

    利用java异步编程的操作,将分解的sql异步执行并最终汇总数据。这里用到了CountDownLatch和ExecutorService,

    // 获取时间段所有天数

    List days = MyDateUtils.getDays(requestParams.getStartTime(), requestParams.getEndTime());

    // 天数长度

    int length = days.size();

    // 初始化合并集合,并指定大小,防止数组越界

    List list = Lists.newArrayListWithCapacity(length);

    // 初始化线程池

    ExecutorService pool = Executors.newFixedThreadPool(length);

    // 初始化计数器

    CountDownLatch latch = new CountDownLatch(length);

    // 查询每天的时间并合并

    for (String day : days) {

    Map param = Maps.newHashMap();

    // param 组装查询条件

    pool.submit(new Runnable() {

    @Override

    public void run() {

    try {

    // mybatis查询sql

    // 将结果汇总

    list.addAll(查询结果);

    } catch (Exception e) {

    logger.error("getTime异常", e);

    } finally {

    //线程结束-1

    latch.countDown();

    }

    }

    });

    }

    try {

    // 等待所有查询结束

    //暂停当前线程,死循环 判断线程数是否结束

    latch.await();

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    // list为汇总集合

    // 如果有必要,可以组装下你想要的业务数据,计算什么的,如果没有就没了

    更多相关内容
  • 本篇文章主要介绍了c#中Winform实现多线程异步更新UI(进度及状态信息) ,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • python多线程异步(一)

    千次阅读 2021-11-28 20:18:30
    现在工作中又遇到必须要通过多线程解决的问题,所以再回顾以前方老师的课程,从头整理一下多线程异步这块知识,方便以后遇到问题可以快速写出代码来。 目录1、多线程异步初步介绍1.1一般的异步demo1.2傀儡线程2、...

    一直想写一个多线程博客,汇总一下方老师教给我们的知识。但是因为一直没有用到,或者自己还没有吃透里面的精髓,所以不敢下笔。现在工作中又遇到必须要通过多线程解决的问题,所以再回顾以前方老师的课程,从头整理一下多线程异步这块知识,方便以后遇到问题可以快速写出代码来。

    1、多线程异步初步介绍

    串行和异步模式如下图,从图上可以很直观看出串行变成和异步编程区别
    在这里插入图片描述
    python 中线程需要用到自带的Threading包,可以使用并发

    1.1一般的异步demo

    import time
    import threading
    
    def syn_method():#串行的普通编程方式
        print("Start")
    
        time.sleep(1)
        print("Visit website 1")
    
        time.sleep(1)
        print("Visit website 2")
    
        time.sleep(1)
        print("Visit website 3")
    
        print("End")
    
    def asyn_method():#异步多线程方式
        print("Start")
    
        def visit1():#注意,这里是在asyn_method函数内部定义visit1函数,在python中是允许这样写的
            time.sleep(1)
            print("Visit website 1")
    
        def visit2():
            time.sleep(1)
            print("Visit website 2")
    
        def visit3():
            time.sleep(1)
            print("Visit website 3")
    
        th1 = threading.Thread(target=visit1)#首先定义多线程
        th2 = threading.Thread(target=visit2)
        th3 = threading.Thread(target=visit3)
    
        th1.start()#其次运行线程,相当于快速按下线程开关,线程启动后继续异步向下执行下面代码
        th2.start()
        th3.start()
    
        th1.join()#最后汇总,等待线程1完成
        th2.join()
        th3.join()
    
        print("End")
    
    asyn_method()#异步多线程函数
    # syn_method()#同步串行函数
    

    上面这个代码包含了线程定义、线程开始、线程阻塞执行三个要点。

    在这里插入图片描述
    在这里插入图片描述

    1.2傀儡线程

    在异步执行的时候,主线程执行完毕后(子线程没有join等待完成),有些子线程可能还没有启动,这时候就需要在主线程执行完毕后把所有没用启动或者正在执行的线程都杀死,避免造成系统垃圾。这时候就要用到傀儡线程,如果设置了傀儡线程,当主线程执行完毕后傀儡线程会自动关闭
    傀儡线程的设置很简单,只需要在设置线程的时候增加daemon=True即可
    把上面代码做了一下改进,1、把join()阻塞代码注释掉;2、在定义线程的时候增加daemon=True;3把sleep时间增加到10秒,便于更好的实验观察
    代码如下:

    import time
    import threading
    
    def syn_method():#串行的普通编程方式
        print("Start")
    
        time.sleep(1)
        print("Visit website 1")
    
        time.sleep(1)
        print("Visit website 2")
    
        time.sleep(1)
        print("Visit website 3")
    
        print("End")
    
    def asyn_method():#异步多线程方式
        print("Start")
    
        def visit1():#注意,这里是在asyn_method函数内部定义visit1函数,在python中是允许这样写的
            time.sleep(10)
            print("Visit website 1")
    
        def visit2():
            time.sleep(10)
            print("Visit website 2")
    
        def visit3():
            time.sleep(10)
            print("Visit website 3")
    
        th1 = threading.Thread(target=visit1,daemon=True)#设置daemon=True,把线程定义成傀儡线程,当主线程结束后,傀儡线程自动关闭,而不会在后台运行
        th2 = threading.Thread(target=visit2,daemon=True)
        th3 = threading.Thread(target=visit3,daemon=True)
    
        th1.start()#其次运行线程,相当于快速按下线程开关,线程启动后继续异步向下执行下面代码
        th2.start()
        th3.start()
    
        #th1.join()#最后汇总,等待线程1完成
        #th2.join()
        #th3.join()
    
        print("End")
    
    asyn_method()#异步多线程函数
    # syn_method()#同步串行函数
    

    增加了傀儡设置后,运行结果如下
    在这里插入图片描述
    各个子线程的结果没用输出,因为在等待的过程中主线程已经执行完毕了,各个子线程被杀死了。
    实验二:把傀儡线程代码daemon=True删掉,或者改为False,结果如下
    在这里插入图片描述
    主线程执行完,但是程序并没有真正结束,等待一会儿子线程结果输出了,程序结束。
    在这里插入图片描述

    在这里插入图片描述

    2、线程锁

    2.1、为什么要锁

    为什么要线程锁,只要有线程定义、线程开始、线程阻塞执行三个要点就够了吗?答案是肯定不够的
    我们来看一个demo
    该demo功能是一个多线程累加和一个多线程累减,
    按照上面已经学到的知识可以很轻松写出下面代码

    2.2、不加锁代码

    import threading
    
    n=0
    def add(num):#累加的函数
        global n
        for _ in range(num):
            n+=1
    
    def sub(num):#减的函数
        global n
        for _ in range(num):
            n -= 1
    
    num = 10000000
    th_add = threading.Thread(target=add,args=(num,))#定义线程,把num传参进去
    th_sub = threading.Thread(target=sub,args=(num,))
    
    th_add.start()#启动线程
    th_sub.start()
    
    th_add.join()#阻塞执行
    th_sub.join()
    
    print("n=",n)
    print("End")
    
    

    简单分析一下,定义了一个多线程的加函数,又定义了一个多线程减函数,分别启动后阻塞等待程序执行完,不管输入的数字是多少,期待的结果总是为0才对,执行完毕后,结果如下:
    在这里插入图片描述
    n为啥不等于0,多换几个数字,依然不等于0
    原因分析:
    在这里插入图片描述
    假设n=100的时候,首先加法线程取出100,然后进行加一操作等于101,但是这时候异步在执行,没有等把101结果返回给n的时候减法函数从内存中取出了n值为100,同样进行了减1操作,结果等于99,这时候99的结果和101结果同时赋值给n,所以这时候n的结果不是99就是101,但是不管结果是99或者101,这个时候n值已经错了(n值原来为100,加了一个数,然后又减了一个数,结果应该还是100才对)。
    所以这时候就要用到线程锁来协调数据,在进行加法或者减法操作的时候希望n值是计算完成,写进去了,这样就不会乱了。
    先在开头定义一把锁:lock = threading.Lock()。加锁有两种写法,可以用 lock.acquire()加锁,lock.release()解锁方法;或者直接with lock方法。
    下面demo分别演示了两种加锁方式

    2.3、加锁代码

    import threading
    lock = threading.Lock()#在开头定义一把锁
    n=0
    def add(num):#加的函数
        global n
        for i in range(num):
            lock.acquire()#加锁方法一。相当于java 的 lock.lock()
            try:
                n+=1
            finally:
                lock.release()#解锁
    
    def sub(num):#减的函数
        global n
        for _ in range(num):
            with lock:#加锁方法二
                n -= 1
    
    num = 10000000
    th_add = threading.Thread(target=add,args=(num,))#定义线程,把num传参进去
    th_sub = threading.Thread(target=sub,args=(num,))
    
    th_add.start()#启动线程
    th_sub.start()
    
    th_add.join()#阻塞执行
    th_sub.join()
    
    print("n=",n)
    print("End")
    

    不管num是多少,结果为0。符合预期结果
    在这里插入图片描述

    3、条件锁

    有锁就够了吗,感觉还不够方便。因为如果我有一个缓冲区(缓冲区可以是个有限长度的列表,也类似于一个内存,内存容量是有限的,缓冲区的容量同样是指有限容量的空间),要在缓冲区内想利用多线程写进数据,同时也想从缓冲区获取数据,获取完数据就删除数据,释放缓冲区空间。缓冲区有大小,所以如果已经满了就写不进去,如果缓冲区没用数据,则获取失败。该问题就是生产者和消费者问题,或者也叫缓冲区问题。这时候就要用到条件锁
    条件锁的定义方法:
    has_data = threading.Condition(lock)#里面要传入一个锁,构成条件锁
    has_loc= threading.Condition(lock)
    一个lock可以有很多Condition,一个Condition只有一个lock。
    Condition里面有个wait方法进行条件阻塞,配合if可以实现带条件的锁定和解锁。
    阻塞的wait方法返回条件有两个,一是激活notify_all;二是timeout时间到了;
    例如下面一个样例:1个lock,赋给了两个Condition,一个是C1,一个是C2;C1下面又有两个线程与其有关th1、th2;C2下面又有两个线程与其有关th3、th4、th5。如果这时候notify_all C1,则下面的th1和th2都活过来了。如果这时候notify_all C2,则th3、th4、th5都活过来了。
    在这里插入图片描述

    3.1、条件锁代码

    下面看看代码

    #程序功能:生产者消费者问题
    import threading
    
    class Buffer:#定义缓冲区类
        def __init__(self,buffer_size:int):
            self.buffer_size = buffer_size#缓冲区大小
            self.buffer = []#用一个列表模拟缓冲区
            lock = threading.RLock()#RLock允许在lock中进行第二次调用acquire()进行锁定,而如果是普通lock,不允许在lock中套入lock的acquire(),这样造成锁死(简单的说:一个锁把带有钥匙的主人给锁住了)。所以一般的RLock比较常用,这种lock相当于java ReentrantLock
            self.has_lock = threading.Condition(lock)#条件锁定义,表示有空位
            self.has_data = threading.Condition(lock)#条件锁定义,表示有数据
    
    
        def put(self,data,blocking = True):#向buffer传入数据,生产者。blocking是判定有没有缓存空间写入数据
            #return True if the data is put into this buffer successfully,False otherwise
            with self.has_lock:
                if blocking:
                    while len(self.buffer)>=self.buffer_size:#条件锁的条件
                        self.has_lock.wait()#阻塞has_lock
                else:
                    if len(self.buffer) >= self.buffer_size:
                        return False
                self.buffer.append(data)
                self.has_data.notify_all()#激活has_data条件锁
                return True
    
    
    
        def get(self,blocking = True):#取数据(消费者)
            with self.has_data:
                if blocking:
                    while len(self.buffer)==0:#取数据等待的条件是缓冲区没用数据
                        self.has_data.wait()#阻塞has_data
                else:
                    if len(self.buffer)==0:
                        return False
                result = self.buffer[0]
                del self.buffer[0]
                self.has_lock.notify_all()#删除了取出的数据,说明有空位了,这时候激活has_lock
                return result
    
    if __name__ == '__main__':
        num = 20
        buffer= Buffer(5)
        def produce(n:int):#生产函数
            for i in range(num):
                data = "data_%d_%d"%(n,i)
                buffer.put(data)
                print(data,"is produced.")
    
        def resume():#消费函数
            for _ in range(num):
                data = buffer.get()
                print(data," is resume.")
    
        th0 = threading.Thread(target=produce,args=(0,))#定义一个多线程,调用生产的函数
        th1 = threading.Thread(target=produce,args=(1,))
        th2 = threading.Thread(target=resume)#定义一个多线程,调用消费的函数
        th3 = threading.Thread(target=resume)
        th0.start()
        th1.start()
        th2.start()
        th3.start()
        th0.join()
        th1.join()
        th2.join()
        th3.join()
        print("The test is End")
    

    就这样吧,后面再在开新文章,增加几个多线程案例。

    展开全文
  • 多线程导入excel 数据

    2018-01-04 21:54:05
    java 多线程导入excel数据,预防高并发,线程同步锁,
  • springBoot多线程+异步处理

    千次阅读 2020-09-17 19:13:43
    <一>: /** * 线程池 * <p> * (1)判断核心线程数是否已满,核心线程数大小和corePoolSize参数有关,未满... * (4)若线程池已满,则采用拒绝策略处理无法执执行的任务,拒绝策略和handler参数有关 *

    <一>:构建线程池

    /**
     * 线程池
     * <p>
     * (1)判断核心线程数是否已满,核心线程数大小和corePoolSize参数有关,未满则创建线程执行任务
     * (2)若核心线程池已满,判断队列是否满,队列是否满和workQueue参数有关,若未满则加入队列中
     * (3)若队列已满,判断线程池是否已满,线程池是否已满和maximumPoolSize参数有关,若未满创建线程执行任务
     * (4)若线程池已满,则采用拒绝策略处理无法执执行的任务,拒绝策略和handler参数有关
     *
     */
    @Configuration
    @EnableAsync
    public class AsyncExecutorConfig {
    
        @Bean(name = "commonAsyncPool")
        // 优先考虑,优先考虑被注解的对象注入
        public Executor commonAsyncPool() {
            ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
            // 线程池创建时候初始化的线程数
            executor.setCorePoolSize(30);
            // 线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程
            executor.setMaxPoolSize(150);
            // 用来缓冲执行任务的队列
            executor.setQueueCapacity(50);
            // 允许线程的空闲时间60秒:当超过了核心线程之外的线程,在空闲时间到达之后会被销毁
            executor.setKeepAliveSeconds(60);
            // 线程池名的前缀:设置好了之后可以方便我们定位处理任务所在的线程池
            executor.setThreadNamePrefix("serverCommonAsyncPool-");
            // 线程池对拒绝任务的处理策略:这里采用了CallerRunsPolicy策略,当线程池没有处理能力的时候,
            // 该策略会直接在 execute 方法的调用线程中运行被拒绝的任务;如果执行程序已关闭,则会丢弃该任务
            executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
            executor.initialize();
            return executor;
        }
    
    
    }
    

    <二>:分离出来需要异步处理的方法

    @Slf4j
    @Service
    @EnableAsync
    public class SubscriptionServiceExecutor {
        @Autowired
        SwsJcCustTmRelativeMapper swsJcCustTmRelativeMapper;
    
        @Async("commonAsyncPool")
        public void insertMessage(List<MessageChildDto> childNode, MessageGroupDto group, Integer messageId, UserInfoDto custInfo, Integer rommId,
                                  String rommName, SwsJcSubscriptionMsg subscriptionMsg) {
            Map keyMap = new HashMap();
            SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            for (MessageChildDto child : childNode) {
                try {
                    if (!keyMap.containsKey(child.getChildId())) {
                        keyMap.put(child.getChildId(), child.getName());
                        SwsJcSubscriptionReceive subscriptionReceive = new SwsJcSubscriptionReceive();
                        subscriptionReceive.setReceiveGroup(group.getName());
                        subscriptionReceive.setMessageId(messageId);
                        if (custInfo.getSourceWay() == null || (!"Android".equals(custInfo.getSourceWay()) && !"iOS".equals(custInfo.getSourceWay()))) {
                            subscriptionReceive.setReceiveUser(child.getChildId());
                        } else {
                            subscriptionReceive.setReceiveUser(child.getKey());
                        }
                        subscriptionReceive.setType(0);
                        subscriptionReceive.setDelStatus(1);//未删除
                        subscriptionReceive.setReceiveUserName(child.getName());
                        subscriptionReceive.setAliasId(child.getKey());
                        AppRoleEnum appRoleEnum = AppRoleEnum.getEnumByType(group.getName());
                        if (appRoleEnum != null) {
                            RoleEnum roleEnum = RoleEnum.getRoleEnumByType(appRoleEnum.getApp());
                            if (roleEnum != null) {
                                subscriptionReceive.setReceiveRole(roleEnum.getTypeName());
                            }
                        }
                        if (rommId != 0) {
                            subscriptionReceive.setRoomId(rommId);
                        }
                        subscriptionReceive.setRoomName(rommName);
                        swsJcSubscriptionReceiveMapper.insertSelective(subscriptionReceive);
    
                        if (custInfo.getSourceWay() == null || (!"Android".equals(custInfo.getSourceWay()) && !"iOS".equals(custInfo.getSourceWay()))) {
                            //发送消息
                            SwsYwSubscriptionInfo subscribeInfo = new SwsYwSubscriptionInfo();
                            subscribeInfo.setTmplId("KfgRqIRTrZeS5D4ABm8_68Y4bUrJsXVMsZdbnm04-3s");
                            subscribeInfo.setOpenId(subscriptionReceive.getReceiveUser());
                            SwsYwSubscriptionInfo scriptionInfo = swsYwSubscriptionInfoMapper.selectByPrimaryKey(subscribeInfo);
                            if (scriptionInfo != null) {
                                try {
                                    Map<String, String> data = new HashMap<>();
                                    data.put("time3", sf.format(subscriptionMsg.getSendDate()));
                                    data.put("thing8", subscriptionMsg.getTheme());
                                    data.put("name9", subscriptionMsg.getSendUserName());
                                    Map res_map = sendSubscribeMessage(subscriptionReceive.getReceiveUser(), subscribeInfo.getTmplId(), "pages/messageAll/index", data);
                                    if (!"ok".equals(res_map.get("errmsg"))) {
                                    }
                                } catch (Exception e) {
                                }
                                swsYwSubscriptionInfoMapper.deleteByPrimaryKey(subscribeInfo);
                            }
                        }
                    }
                } catch (Exception e) {
                    log.error("消息发送失败:{}" + child.toString() + "/" + messageId);
                }
            }
        }
    

    <三>调用该异步方法
    注意:分离出来的异步方法与调用者不要在同一个类种,如果需要放入同一个类中,需要先获取该类的代理类,通过代理类取调用分类出来的方法

     //发送人员数量过大时,异步处理
     //异步处理时候,执行步骤一,然后执行步骤三,直接返回给前端 结果1, (步骤二与步骤三异步执行,其中步骤二是多线程处理,结果返回给前端时,步骤二不一定执行完毕了)
      String userRole = userInfoDto.getRoleCode();//步骤一
         
      subscriptionServiceExecutor.insertMessage(childNode, group, messageId, custInfo, rommId, rommName, subscriptionMsg);//步骤三
           
      String roleSelect = userInfoDto.getRoleSelect();//步骤三
      return 1;
    

    题外:
    一:对于tomcat这种web服务器而言,每一次请求。都会创建一条线程,对于全局变量,需要考虑线程安全问题,
    二:对于需要异步处理的业务,子线程与父线程也需要考虑线程安全问题。(父线程的成员变量相对于子线程就是全局变量)
    三:对于异步的代码,单次请求需要1分钟完成,在1分钟之内,再次请求多次,采用的是多线程处理(自行配置线程池),此时父线程的变量,对于子线程而言,存在线程安全问题。

    展开全文
  • 多线程异步处理时的事务管理

    千次阅读 2021-01-25 16:44:12
    下面的代码就是在单个项目中使用多线程异步处理时的事务管理的方法。 具体思路打个比方来说明一下: 代码噼里啪啦的一顿敲,终于把需求实现了。 现在想休息几分钟,但公司比较抠,只能让你休息三分钟,三分钟后...

    分布式事务介绍:https://zhuanlan.zhihu.com/p/183753774

    前言:项目中在保证数据一致性的前提下还想提高执行效率,有什么好办法么?使用多线程肯定是首先想到的,但多线程之间的事务怎么保持一致呢?下面的代码就是在单个项目中使用多线程异步处理时的事务管理的方法。

    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.transaction.PlatformTransactionManager;
    import org.springframework.transaction.TransactionDefinition;
    import org.springframework.transaction.TransactionStatus;
    import org.springframework.transaction.support.DefaultTransactionDefinition;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.atomic.AtomicReference;
    import java.util.function.Supplier;
    
    /**
     * 多线程异步处理时的事务管理
     * 1.addFunction 添加要异步执行的方法
     * 2.execute方法中,使用全局的计数器和异常标记字段,统计个异步线程执行的结果
     *      当所有异步线程执行完之后,根据异常标记字段判断是回滚还是提交事务。
     */
    public class MultiThreadTransactionComponent {
        Logger logger= LoggerFactory.getLogger(this.getClass());
    
        private PlatformTransactionManager platformTransactionManager;
        private ThreadPoolExecutor threadPoolExecutor;
    
        private List<Supplier> supplierList=new ArrayList();
        // 创建执行计数器
        private CountDownLatch countDownLatch;
        // 是否存在异常
        AtomicReference<Boolean> isError = new AtomicReference<>(false);
    
        public MultiThreadTransactionComponent(PlatformTransactionManager transactionManager,ThreadPoolExecutor threadPoolExecutor){
            this.platformTransactionManager=transactionManager;
            this.threadPoolExecutor=threadPoolExecutor;
        }
    
        /**
         * 添加要异步执行的方法程序
         * @param supplier
         */
        public void addFunction(Supplier supplier){
            supplierList.add(supplier);
        }
    
        public void execute(){
            countDownLatch=new CountDownLatch(supplierList.size());
            logger.info("【多线程事务】开始...");
            for(Supplier supplier:supplierList){
                this.threadPoolExecutor.submit(new TransactionRunnable(platformTransactionManager,supplier));
            }
            try {
                countDownLatch.await();
                if(isError.get()) {
                    logger.error("【多线程事务】多线程执行失败,事务已回滚");
                    // 主线程抛出自定义的异常
                    throw new RuntimeException("多线程执行失败");
                }
                logger.info("【多线程事务】多线程执行完成,事务已提交");
            } catch (InterruptedException e) {
                logger.error("多线程执行失败");
                // 主线程抛出自定义的异常
                throw new RuntimeException("多线程执行失败"+e.getMessage());
            }
        }
    
    
        class TransactionRunnable implements Runnable{
    
            private PlatformTransactionManager platformTransactionManager;
            private Supplier supplier;
    
            public TransactionRunnable(PlatformTransactionManager platformTransactionManager, Supplier supplier) {
                this.platformTransactionManager=platformTransactionManager;
                this.supplier=supplier;
            }
    
            @Override
            public void run() {
                DefaultTransactionDefinition def = new DefaultTransactionDefinition();
                def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
                TransactionStatus transaction = this.platformTransactionManager.getTransaction(def);
                try {
                    this.supplier.get();
                } catch (Exception e) {
                    //设置错误标记
                    isError.set(true);
                    logger.error("【多线程事务】执行失败{}",e.getMessage());
                }
                countDownLatch.countDown();
                try{
                    countDownLatch.await();
                    if(isError.get()){
    //                    logger.info("【多线程事务-子线程】事务回滚");
                        //事务回滚
                        platformTransactionManager.rollback(transaction);
                    }else {
    //                    logger.info("【多线程事务-子线程】事务提交");
                        //事务提交
                        platformTransactionManager.commit(transaction);
                    }
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
            }
        }
    
    }
    

    使用示例:

        @Autowired
        PlatformTransactionManager platformTransactionManager;
        @Autowired
        private ThreadPoolExecutor threadPoolExecutor;
        @Test
        public void testTransaction(){
            MultiThreadTransactionComponent mttc = new MultiThreadTransactionComponent(platformTransactionManager,threadPoolExecutor);
            for(int k=0;k<10;k++){
                int i = RandomUtils.nextInt(0, 5);
                int y=RandomUtils.nextInt(0,5);
                //添加要执行的业务代码
                mttc.addFunction(()->{
                    System.out.println("当前线程:" + Thread.currentThread().getName());
                    System.out.println(i%y);  //除数为0时 执行失败
                    MarketGeomUpLog marketGeomUpLog=new MarketGeomUpLog();
                    marketGeomUpLog.setContent(i+"--"+y);
                    marketGeomUpLogMapper.addLog(marketGeomUpLog);
                    return 0;
                });
            }
            mttc.execute();
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
    展开全文
  • Android多线程和常用异步处理技术

    千次阅读 2022-03-25 09:37:58
    Android多线程和常用异步处理技术 一、Android多线程概述 1.概述:表示一个程序的多段语句同时执行,但并不等于多次启动一个程序,操作系统也不会把每个线程当作独立的进程来对待。 2.线程和进程的区别: ①两者粒度...
  • 处理大量数据时,想要快速的处理完毕,就需要使用多线程 + 批量(插入等)处理!!! 采用简单粗暴的形式来告诉你们如何使用多线程+批量插入 来处理千万级的数据》》》 批量插入的方法: 接下来就是获取要...
  • Java多线程分批处理数据

    千次阅读 2019-03-17 11:59:22
    场景:发短信,当有数据量庞大的短信需要发送时,可以采用多线程的方式分批处理以提高效率,但线程要控制合适的数量,否则会极大消耗CPU资源 上代码: 创建分页类PageUtil /** * 分页 * @param list 切割数据...
  • 多线程分批处理数据

    千次阅读 2019-06-05 17:17:06
    然后使用多线程进行异步发送 步骤 1.初始化数据 2.定义每个线程分批发送大小 3.计算每个线程需要分批跑的数据 4.进行分批发送 实例: 实体类: package com.emple.entity; import java.security.SecureRa...
  • 多线程异步加载数据过程

    热门讨论 2013-01-03 20:32:15
    利用异步调用,及跨线程处理技术,完全可以在不同线程或窗体上来显示加载数据过程,并在加载过程,可以随时终止,全过程实用用很强!
  • Spring boot多线程异步查询

    千次阅读 2021-03-22 16:08:07
    SpringBoot多线程异步查询步骤 1、创建线程池 import java.util.concurrent.ThreadPoolExecutor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation....
  • Springboot异步多线程编程

    千次阅读 2022-01-04 19:55:52
    同步、异步、进程、线程,springboot异步多线程编程学习
  • 因此可以使用异步调用的方法,不阻塞当前其他任务的执行。 小栗子 首先我们先要创建一个线程池,可以根据自己的需求创建,什么IO密集型参数设置,CPU密集型参数的设置。这里我们仅仅想让10个任务一起跑。 ...
  • python异步多线程

    千次阅读 2022-04-27 20:32:56
    Python异步多线程 首先,我们需要先明白同步和异步的区别: 同步:同步是指一个进程在执行某个请求的时候,如果该请求需要一段时间才能返回信息,那么这个进程会一直等待下去,直到收到返回信息才继续执行下去。 ...
  • Java使用多线程异步执行批量更新操作

    千次阅读 热门讨论 2021-01-11 00:16:32
    因此,开多线程来执行批量任务是十分重要的一种批量操作思路,其实这种思路实现起来也十分简单,就拿批量更新的操作举例: 整体流程图 步骤 获取需要进行批量更新的大集合A,对大集合进行拆分操作,分成N个小集合A...
  • 启动类添加 @EnableAsync 注解 开启线程池(多线程) 新增异步添加接口 package com.chalk.service; import com.chalk.model.Student; import com.chalk.model.Teacher; import com.chalk.model.UserDeviceRel...
  • 在微服务中,多线程异步+Feign调用会出现请求头丢失 解决 在主线程中先获取请求头参数 传入子线程中 由子线程将请求头参数设置到上下文中 最后在Feign转发处理中拿到子线程设置的上下文的请求头数据,转发到下游。 ...
  • 多线程异步的区别

    千次阅读 2020-12-21 15:22:41
    文章目录前言一、什么是异步二、什么是多线程三、异步多线程异同点四、异步多线程适用场景五、思考题总结 前言 异步是一种现象结果,多线程是实现其结果的一种手段。不可将多线程编程与异步划上等号 譬如,单...
  • java多线程异步使用

    千次阅读 2021-02-25 20:01:50
    在编程中,根据实际场景,我们有时会考虑使用异步执行来提高应用的响应速度;一个简单的例子:@Testpublic void futureTest() {// 注意使用 ExecutorService 而非 ExecutorExecutorService executorService = Executors....
  • C#:多线程异步

    千次阅读 2021-08-19 14:41:26
    多线程 介绍: 多线程(multithreading),是指从软件...具有多线程能力的计算机因有硬件支持而能够在同一时间执行多余一个线程,进而提升整体处理性能。--来自百度百科 分类: 原生线程: 托管线程: .........
  • <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> yml文件添加多线程核心配置 server: #端口号...
  • 为了方便以后的开发,写了个异步多线程批处理的组件 具体用法见代码里的说明。很多时候都需要处理大批量数据,以后就方便多了
  • C#异步操作 异步查询数据库 异步处理一行一行加载数据
  • springboot中多线程批量处理数据

    千次阅读 2020-06-07 17:24:28
    /** * syncMargePsr:(多线程同步处理数据方法). * * @param bookList 一段数据集合 * @param pageIndex 段数 * @return Future future对象 * @author LW * @since JDK 1.8 */ @Async(value = "BookTask") public...
  • 多线程异步调用接口数据同步问题

    千次阅读 2019-08-27 18:16:00
    多线程进行接口调用时如果调用的接口执行时间不同会直接跳过慢的接口,导致最终数据出错。 PrintUtil类模拟被调用的2个接口方法 ThreadDemo类是多线程的实现类 Test类是调用方。 注释掉f1.join()时执行结果:...
  • .Net 异步多线程总结

    千次阅读 2018-09-02 01:36:50
    多线程虽然能够提升程序的运行效率,但是消耗的资源更多,所以线程并不是越多越好。 二、同步和异步 同步和异步都是针对方法而言; 同步方法指的是程序按照顺序执行,必须等待上一操作完成后才能继续往后执行; ...
  • 多线程处理数据数据

    千次阅读 2020-07-01 22:22:25
    数据量还蛮大的,大约50-60万数据(一条一条执行),其中还涉及到与其他接口的交互,因此这些数据跑下来要耗时很久,因此设计了一个方案,使用多线程的方式进行处理。 方案1 每次重数据库表中取一定量的数据...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 333,784
精华内容 133,513
关键字:

多线程异步处理数据