精华内容
下载资源
问答
  • 针对之前转载文章https://mp.csdn.net/console/editor/html/100921632里的多线程处理订单方式进行改进,并持续学习持续优化! public void dealOrders() { AtomicLong count = new AtomicLong(0); try { // ...

    针对之前转载文章https://mp.csdn.net/console/editor/html/100921632 里的多线程处理订单方式进行改进,并持续学习持续优化!

     

    public void dealOrders() {
            AtomicLong count = new AtomicLong(0);
            try {
                // TODO 此处使用修改为 要处理订单集合
                List<String> ts = new ArrayList<>();
                // 订单数 根据实际情况处理 0
                int MAX_ORDERS = 0;
                // 根据一定规则获取线程数
                int max_threads = GetDealOrdersThreadsNum.getMAX_THREADS(MAX_ORDERS);
    
                ExecutorService executor = Executors.newFixedThreadPool(max_threads);
                Future<?> submit = null;
                for (String t : ts) {
                    submit = executor.submit(() -> {
                        try {
                            synchronized (t) {
                                //处理订单
    
                                //  订单处理成功计数器
                                count.getAndIncrement();
                            }
                        } catch (Exception e) {
                            // 异常打印
                        }
                    });
                }
                executor.shutdown();
                while (true) {
                    if (executor.isTerminated()) {
                        break;
                    }
                }
            } catch (Exception e) {
                // 异常打印
            } finally {
                // 释放资源
            }
        }

     有更好的方案可以传授一下! 谢谢!

     

     

    下次试下集成线程池.

    每次的进步都离不开持之以恒的坚持!!!

    展开全文
  • 问题描述:假如客户给你... 以多线程的方式去处理,1000的个订单我就创建1000个线程去处理,那么总耗时就只有1秒!(很明显,客户喜欢这种方式) 如何实施(因为资源的问题,不能创建1000个线程): 我现在先假设用

    问题描述:假如客户给你丢过来1000个订单,这些订单都需要1到2秒的处理时间。你怎么以最快的速度完成处理并保存到数据库?

    问题解析:设每个运单处理需要1秒的时间。

    1. 以传统的方式去处理,我写个循环,一个订单一个订单地去处理,那么总耗时为:1*1000=1000秒(约等于17个分钟,那客户还不急死?)

    2. 以多线程的方式去处理,1000的个订单我就创建1000个线程去处理,那么总耗时就只有1秒!(很明显,客户喜欢这种方式)

    如何实施(因为资源的问题,不能创建1000个线程):

    我现在先假设用户丢过来13条数据,由于资源的问题我们只能创建5个线程,那么每个线程应该处理几条数据?

    int per = data.size() / 5 = 2,这样一来每个线程只能处理两个,那么还剩下3个怎么办?

    package org.java.test4;
    
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    import java.util.concurrent.FutureTask;
    
    public class ThreadDemo {
    
    	private static class ProcessDataTask implements Callable<String> {
    
    		private List<String> data = new ArrayList<>();
    
    		public void add(String item) {
    			data.add(item);
    		}
    
    		@Override
    		public String call() throws Exception {
    			//处理数据
    			for (String item : data) {
    				System.out.println(Thread.currentThread().getName() + "-data:" + item);
    			}
    			
    			//模拟数据处理需要1秒钟
    			Thread.sleep(1000);
    			
    			//最后返回你想返回的东西
    			return Thread.currentThread().getName();
    		}
    	}
    
    	public static void main(String[] args) throws Exception {
    		//模拟客户数据,假设现在客户上传了13条数据
    		List<String> userData = new ArrayList<String>();
    		for (int i = 1; i <= 13; i++) {
    			userData.add("jackson_" + i);
    		}
    
    		//构造线程,假设总的线程数为5个
    		int totalThreadNum = 5;
    		List<ProcessDataTask> tasks = buildThread(userData, 5);
    
    		//构造线程池,然后执行每一个线程
    		ExecutorService executorService = Executors.newFixedThreadPool(totalThreadNum);
    		List<Future<String>> threadResults = executorService.invokeAll(tasks);
    		executorService.shutdown();
    		
    		//遍历线程结果
    		for (Future<String> future : threadResults) {
    			try {
    				FutureTask<String> futureTask = (FutureTask<String>) future;
    				System.out.println("thread return value: " + futureTask.get());
    			} catch (Exception e) {
    				e.printStackTrace();
    			}
    		}
    
    	}
    	
    	/**
    	 * 根据数据和线程数为每一个线程分配数据
    	 * @param data
    	 * @param totalThreadNum
    	 * @return
    	 * @throws Exception
    	 */
    	public static List<ProcessDataTask> buildThread(List data, int totalThreadNum) throws Exception {
    		int nThreads = totalThreadNum;
    		int perThreadDataNum = data.size() / nThreads;
    		int remainDataNum = data.size() % nThreads;
    		
    		List<ProcessDataTask> tasks = new ArrayList<ProcessDataTask>();
    		for (int i = 0; i < nThreads; i++) {
    			ProcessDataTask processDataTask = new ProcessDataTask();
    			Iterator iterator = data.iterator();
    			int j = 0;
    			while (j < perThreadDataNum && iterator.hasNext()) {
    				processDataTask.add((String) iterator.next());
    				iterator.remove();
    				++j;
    			}
    			if (remainDataNum > 0) {
    				processDataTask.add((String) iterator.next());
    				iterator.remove();
    				remainDataNum--;
    			}
    			tasks.add(processDataTask);
    		}
    		
    		return tasks;
    	}
    
    }

     

    展开全文
  • 模拟多线程并发订单处理功能实现

    千次阅读 2018-01-13 17:14:28
    实现思路也比较简单,就是处理每笔订单的时候加个锁,无论是手动还是自动,都需要取得订单锁后才能处理,待处理订单队列方面,因为要考虑并发动态的添加或移除订单元素,暂时采用CopyOnWriteArrayList...

    在目前的应用开发中,有一个需要自动处理某状态订单的功能,需要和手动处理功能并行不能冲突和重复处理。目前大致写了一下demo实现,记录一下,方便以后有时间复习和改进。实现思路也比较简单,就是处理每笔订单的时候加个锁,无论是手动还是自动,都需要取得订单锁后才能处理,待处理订单队列方面,因为要考虑并发动态的添加或移除订单元素,暂时采用CopyOnWriteArrayList(ConcurrentHashMap也可以)来实现。加锁和解锁的过程都加了令牌,一来方便测试时验证加锁和解锁的是否为同一线程;二来也可以避免工程中误调解锁功能而导致程序出错。感觉对线程这块的知识掌握的还是不够深入,以后要多多加强。代码如下:

    import java.util.List;
    import java.util.UUID;
    import java.util.concurrent.CopyOnWriteArrayList;
    import java.util.concurrent.CyclicBarrier;
    
    public class ThreadTest {
        //需要处理的订单数量,
        private static int MAX_ORDERS=10000;
        //最大线程数
        private  static  int MAX_THREADS =100;
        //每个线程睡眠时间(订单处理时间)
        private static  int SLEEP =10;
        //写复制list,支持并发修改和遍历功能,需要注意内存耗费的问题,可以采用ConcurrentHashMap等代替
        private static  List<Order> list=new CopyOnWriteArrayList<>();//new CopyOnWriteArrayList<>();//new ArrayList<>();
        static {//初始化测试数据
            for(int i=0;i<MAX_ORDERS;i++)
                list.add(new Order("HHHH"+i));
        }
        public  static  void main(String ss[]){
            /**
             * 记录开始时间,理论上耗时略大于MAX_ORDERS×SLEEP/MAX_THREADS
             */
            Long t=System.currentTimeMillis();
            //同步屏障,以是住线程能等待所有线程结束,并记录下耗时
            final CyclicBarrier cyclicBarrier=new CyclicBarrier(MAX_THREADS+1);
            for(int i = 0; i< MAX_THREADS; i++){//创建并启动订单处理线程
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                            while (!list.isEmpty()) {
                                Order order = null;
                                //生成唯一加锁令牌,保证唯一性即可
                                String uuid = UUID.randomUUID().toString();
                                int i = 0;//记录查找到未处理的订单位置
                                for (Order item : list) {
                                    i++;
                                    if (item.getLock(uuid)) {//找到并锁定订单
                                        order = item;
                                        break;
                                    }
                                }
                                if (order != null) {//获取到可处理的订单
                                    System.out.println(i + ":" + Thread.currentThread().getId() + "(" + SLEEP + ")正在处理订单:" + order.getApplyNo());
                                    try {
                                        Thread.sleep(SLEEP);//模拟订单处理功能
                                        list.remove(order);//处理成功后将订单重待处理列表中移除
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }finally {
                                        /**
                                         * 无论成功还是失败,都需要解锁订单
                                         * 失败情况下订单依旧留在待处理列表中,供其他线程处理
                                         * 可以根据实际情况将处理失败的订单转移到别的地方进行处理
                                         * 否则会导致坏订单影响后面正常订单的处理
                                         */
                                        order.unLock(uuid);//解锁订单
                                    }
    
                                }
    
                            }
                            try {
                                cyclicBarrier.await();
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
    
                        }
    
                }).start();
            }
            try{
                //等待所有线程执行完成
                cyclicBarrier.await();
            }catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("*******订单处理完成,耗时:"+(System.currentTimeMillis()-t)+"ms");
    
        }
    
        static  class  Order{
            private String applyNo;
    
            public  Order(String applyNo){
                this.applyNo=applyNo;
            }
            public String getApplyNo() {
                return applyNo;
            }
            private    boolean  lock=true;
            //用来检验加锁和解锁的是否为同一线程
            private  String token="";
    
            /**
             * 加锁,先判断是否已被锁住,未被锁住则获取该对象锁
             * @param token
             * @return
             */
            public boolean getLock(String token){
                if(lock){
                    synchronized (this){
                        if(lock){//双重检测
                            lock=false;
                            this.token=token;
                            return true;
                        }else{
                            System.out.println("被别人抢走了!!!!!!!!!!");
                        }
    
                    }
    
                }
                return lock;
            }
    
            /**
             * 解锁,通过token限定只有获取到锁的线程才能解锁,否则为非法调用
             * @param newToken
             */
            public void unLock(String newToken){
                if(!newToken.equals(this.token)||lock){
                    System.out.println("出错了!!!!!!!!!!");
                }else{
                    lock=true;
                }
            }
    
        }
    }
    

    展开全文
  • 假设订单下发, 采用单机... 所以采用多节点多线程处理三方商家的订单接入系统. 流程图: 如图所示: 采用多节点, 多线程, 使用curator操作zk的方式实现, 订单的下发. 以前的方式每分钟下发100单, 之后采用现在的...

     假设订单下发, 采用单机每分钟从订单OrderEntry接口表中抓100单, 接入订单oms系统中. 由于双十一期间, 订单量激增, 导致订单单机每分钟100单造成, 订单积压. 所以采用多节点多线程处理三方商家的订单接入系统.

    流程图:

    如图所示:

    采用多节点, 多线程, 使用curator操作zk的方式实现, 订单的下发.

    以前的方式每分钟下发100单, 之后采用现在的方式可以每分钟2000单, 大大增加系统的订单下发的处理速度, 系统的吞吐量, 提高了效率.

    1 操作zookeeper的工具类:

    import org.apache.curator.RetryPolicy;
    import org.apache.curator.framework.CuratorFramework;
    import org.apache.curator.framework.CuratorFrameworkFactory;
    import org.apache.curator.framework.recipes.locks.InterProcessMutex;
    import org.apache.curator.retry.ExponentialBackoffRetry;
     
    public class ZkUtils {
     
        private static final String zkStr = ConfUtil.getProperty("zkStr");
        private static final String zkPath = ConfUtil.getProperty("zkPath");
        
        public static InterProcessMutex createMutexLock(){
            
            RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 10); //1 重试策略:初试时间为1s 重试10次
            
            CuratorFramework client = CuratorFrameworkFactory.builder()//2 通过工厂创建连接
                        .connectString(zkStr)
                        .sessionTimeoutMs(5000)
                        .retryPolicy(retryPolicy)
                        .build();
            client.start(); // 开启连接
            InterProcessMutex mutexLock = new InterProcessMutex(client, zkPath); // 创建分布式锁
            return mutexLock;
            
        }
    }

    2 使用该工具类处理订单下发业务逻辑

    public class Job {
        private final static org.slf4j.Logger logger=LoggerFactory.getLogger(HnJob.class);
     
        @Autowired
        private IHNOrderService iHNOrderService;
        
        public void execute(){
            
            InterProcessMutex mutexLock = ZkUtils.createMutexLock();
            try{
                mutexLock.acquire();
                bizHandler(); //执行订单下发业务处理逻辑
                
            }catch (Exception e) {
                e.printStackTrace();
            }finally{
                try {
                    mutexLock.release();
                } catch (Exception e) {
                    e.printStackTrace();
                } 
            }
        }
        
        void bizHandler(){
            long start=System.currentTimeMillis();
            logger.info("====================订单下发开始");
            iHNOrderService.hnOrderQuery();
            long end=System.currentTimeMillis();
            logger.info("=================订单下发结束,耗时={}秒",(end-start)/(1000));
        }
        
        
        
    }

     

    转载于:https://www.cnblogs.com/diaozhaojian/p/10582700.html

    展开全文
  • java 中Future是一个未来对象,里面保存这线程处理结果,它像一个提货凭证,拿着它你可以随时去提取结果。在两种情况下,离开Future几乎很难办。一种情况是拆分订单,比如你的应用收到一个批量订单,此时如果要求最...
  • Java多线程实现订单模式: 客户端线程向服务端发起请求后,请求处理需要较长时间处理,这个时候客户端又需要及时得到一个结果响应,这好比我们去蛋糕店订蛋糕,蛋糕往往需要几个小时才能完成,这个时候店员就会给...
  • 多线程程序结构: using System; using System.Collections; using System.Configuration; using System.Threading; using System.Transactions; using PetShop.BLL; using PetShop.Model; namespace PetShop....
  • 想实现异步发送邮件的功能,比如说,在客户成功提交了一个订单时,程序...只不过有了futuredata可以用来存储结果 仍然是主线程立即结束返回响应 新启线程异步做委托的任务 主线程利用空闲时间去做其他事 多线程资源利
  • 多线程一般使用在进行io操作。 多线程一般使用在进行io操作。 在python中由于GIL线程就是“鸡肋” 使用场景: 创建订单时候, 对于每张表都可以使用线程进行操作。 比如一个业务逻辑需要并行的操作几个文件的读写,...
  • mysql增加version字段实现乐观锁,实现高并发下的订单库存的并发控制,通过开启多线程同时处理模拟多个请求同时到达的情况 ============================================================= 完整的代码请到GIthub...
  • 问题描述:某仓储系统波次定位时,单波次无积压(10000订单,4500sku...优化方案:调用stock接口时采用多线程方式,需注意对stock应用资源的影响。 优化前相关代码 优化后代码 优化结果: 优化后: 1)调..
  • 业务场景:在查询订单的时候如何增加处理效率,处理的过程中代码对订单的数据进行了循环,查询数据库进行替换值。导致返回速率很低。 首先我的想法将最原始的数据集合进行拆分,分批处理。 集合拆分执行: //...
  • 多线程解决导出excel性能问题

    千次阅读 2019-05-14 15:54:44
    多线程导出优点 处理速度快 异步导出,可以先返回结果给页面 多线程导出思路: 多个线程完善订单信息,另起一个线程拿到所有数据后导出为Excel 多个线程完善订单信息并生成Excel,另起一个线程将所有子Excel合并...
  • 为何要使用多线程

    2018-05-21 20:45:34
    2.更快的响应时间 试想,一笔订单的创建,有数据插入,订单快照生成,发送邮件或通知给客户,这一系列操作都要有一个过程,计数等等操作,多线程就能很快的处理这个问题3.更好的编程模型 使于开发人员更专注于解决...
  • 多线程中的事务问题

    千次阅读 2020-10-21 20:28:38
    所以第一考虑就是使用多线程分别将各个订单进行推送,并且一个报错,所有线程回滚。 一开始总感觉能用一个事务处理所有的线程,但是凭借自己对@transactional的底层实现和编程事务的比较浅显的认识没有
  • 信号量Semaphore是一个并发工具类,用来控制可同时并发的线程数,其内部维护了一组虚拟许可,通过构造器指定许可...比如说我们现在要处理一批订单,(如下单,取消,或者对账),订单量比较多,才用多线程处理 先创...
  • java多线程异步实例

    2012-11-19 11:17:28
    java线程异步案例,以三个线程作为案例典型,同时发起三个线程,根据不同的订单领取各自的物品,自作过程同步处理
  • 多线程的设计模式

    2017-04-24 09:46:00
    并行设计模式属于设计优化的一部分,它是对一些常用的多线程结构的总结和抽象。与串行程序相比,并行结构的程序通常更为复杂。因此合理的使用并行模式在多线程开发中更具有意义,在这里主要介绍future、master-...
  • 多线程之Future使用详解

    千次阅读 2018-11-22 16:03:28
    Future是一个未来对象,里面保存这线程处理结果,它像一个提货凭证,拿着它你可以随时去提取结果 什么时候使用 在两种情况下,离开Future几乎很难办。 一种情况是拆分订单,比如你的应用收到一个批量订单,此时如果...
  • 客户端发送一个长时间的请求,服务端不需等待该数据处理完成便立即返回一个伪造的代理数据(相当于商品订单,不是商品本身),用户也无需等待,先去执行其他的若干操作后,再去调用服务器已经完成组装的真实数据。...
  • 上一节说了多线程编程的相关问题,当然我在写自己这套交易系统的时候,刚开始使用的就是多线程的方式来实现具体的操作,包括订单处理,行情数据的拉取等。 但是由于网络的延迟、 python对于网络解析和多线程的切换...

空空如也

空空如也

1 2 3 4 5 ... 18
收藏数 357
精华内容 142
关键字:

多线程处理订单