`
zy116494718
  • 浏览: 476779 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

ThreadLocal线程池实例

 
阅读更多

学习了多线程的理论后,下面我们来看工作中遇到的一个具体实例。

 

 

    public Integer startAreaIndex(List<Long> activityIds) {
        //获取所有常规频道的区块,这里得到的区块为4个,所以最终会启用4个线程
        List<Area> areaList = areaServiceStub.queryAreaListByActivityIds(activityIds);
        LogTypeEnum.ACTIVITY_SOLR.info("solr开始索引,场频频道活动下的区块list:{}", areaList);
        if (CollectionUtils.isEmpty(areaList)) {
            return -1;
        }
        LogTypeEnum.ACTIVITY_SOLR.info("-----------------solr常规频道全量索引开始-----------------");
        //一个区块执行一个线程
        Iterator<Area> areaIterator = areaList.iterator();
        while (areaIterator.hasNext()) {
            Area area = areaIterator.next();
                AreaApplyTask areaApplyTask = new AreaApplyTask();
                areaApplyTask.setArea(area);
                areaApplyTask.setSolrWareService(solrWareService); //从这里注入的话,AreaApplyTask 就不用实现Spring的接口了
                areaApplyTask.setSolrActivityService(solrActivityService);
                areaApplyTask.setSolrPromoService(solrPromoService);
                solrIndexTaskExecutor.execute(areaApplyTask);
        }
        try{
            Thread.sleep(1000);   //这里先睡眠1秒,防止创建线程的时间长,导致下面第一次取活跃线程数为0,然后就直接break了
        }catch (Exception e){
            LogTypeEnum.ACTIVITY_SOLR.error("Solr线程索引失败", e);
        }
        for (; ; ) {
            int count = solrIndexTaskExecutor.getActiveCount();
            LogTypeEnum.ACTIVITY_SOLR.info("Solr Index Active Threads : " + count);
            try {
                Thread.sleep(1000);  //每隔1秒判断一次活跃线程数
            } catch (InterruptedException e) {
                LogTypeEnum.ACTIVITY_SOLR.error("Solr线程索引失败", e);
                return -1;
            }
            if (count == 0) {
                break;
            }
        }
        return 0;
    }

 

   AreaApplyTask类:

 

   

public class AreaApplyTask implements Runnable{

    private Area area;
    private WareService solrWareService;
    private PromoService solrPromoService;
    private ActivityService solrActivityService;

    public void run() {
        Area area = getArea();
        if(area != null && area.getType() != null){
            Integer areaType = area.getType();
            if(areaType.equals(AreaType.PROMO.getType())){  //促销区块
                //促销
                solrPromoService.indexByArea(area);
            }else if(areaType.equals(AreaType.WARE.getType())){
                //商品
                solrWareService.indexByArea(area);
            }else if(areaType.equals(AreaType.SHOP.getType())){
                //活动
                solrActivityService.indexByArea(area);
            }else if(AreaType.BRAND.isEqual(areaType)){
                //活动
                solrActivityService.indexByArea(area);
                //促销
                solrPromoService.indexByArea(area);
            }
        }
    }

    public Area getArea() {
        return area;
    }

    public void setArea(Area area) {
        this.area = area;
    }

    public void setSolrWareService(WareService solrWareService) {
        this.solrWareService = solrWareService;
    }

    public void setSolrPromoService(PromoService solrPromoService) {
        this.solrPromoService = solrPromoService;
    }

    public void setSolrActivityService(ActivityService solrActivityService) {
        this.solrActivityService = solrActivityService;
    }
}

 

    

public long indexByArea(Area area){
        /*
           这里为了方便多台机器可以同时跑,而且时间可以从页面传过来,采用了redis的方式,这里
           key为money,value的值在页面上设的为需要重刷solr的批次日期,例如:2016-12-07 00:00:00|2016-12-08 00:00:00|
           这里表示需要重新刷solr的批次日期为12月7日和8日,第一个机器执行后,第二个机器就会跑第二个时间
         */

        String key ="money";
        String time = activityUtilService.getRedisKeyValue(key);
        String beginTime = time.substring(0,time.indexOf("|"));
        String nextBeginTime = time.substring(time.indexOf("|")+1);
        activityUtilService.setInfoToRedisKey(key,1000*60*60,nextBeginTime);

        Batch batch = new Batch();
        batch.setActivityId((long)158001);
        batch.setBeginTime(DateUtil.createDate(beginTime, "yyyy-MM-dd HH:mm:ss"));
        batch.setEndTime(DateUtil.addDay(batch.getBeginTime(),1));
        List<Batch> batchList = batchServiceStub.getBatchTimeLineRangeList(batch);
        List<Long> batchIdList = new ArrayList<Long>();
        for(Batch batch1:batchList){
            batchIdList.add(batch1.getId());
        }
        Long areaId = area.getId();
        ApplyWareParam applyWareParam = new ApplyWareParam();
        applyWareParam.setBatchIdList(batchIdList);
        applyWareParam.setStatus(0);
        List<ApplyWare> applyWareList = applyWareServiceStub.getApplyWareListByBatchIds(applyWareParam, 1, 10000);
        LogTypeEnum.ACTIVITY_SOLR.warn("applyWareList=="+applyWareList.size()+",areaId="+area.getId());
        if(CollectionUtils.isEmpty(applyWareList)){
            return -1L;
        }
        ApplyPromoInfo applyPromoInfoParam = new ApplyPromoInfo();
        applyPromoInfoParam.setAreaId(areaId);
        //查出该区块下的所有促销提报列表
        List<ApplyPromoInfo> applyPromoInfoList = applyPromoInfoDao.queryForList(applyPromoInfoParam,1,Integer.MAX_VALUE);

        //把applyPromoInfoList中的促销ID合并到applyWareList中
        mergePromoListToWareList(applyWareList,applyPromoInfoList);

        return index(applyWareList);
    }

 

 

0
0
分享到:
评论

相关推荐

    ThreadLocal 内存泄露的实例分析1

    at 中专门为每一个 web 应用实例创建的类加载器,它负责加载该 web 应用下的所有类。当 web 应用被卸载时,WebappClassLoader 本应随之被垃圾收集器回收。然而,如果存在对 WebappClassLoader 的强引用,那么这个类...

    vb 多线程 实例(thread 类创建)

    VB中,可以使用`ThreadLocal`类实现这一功能。 7. **线程池**: 除了手动创建线程,VB还提供了线程池,它能更有效地管理线程。线程池会复用已存在的线程,减少创建和销毁线程的开销。通过`ThreadPool....

    ThreadLocal_ThreadLocal源码分析_

    在ThreadLocal中,每个实例都有一个内部Map,这个Map存储了键值对,键是ThreadLocal实例,值就是线程本地的变量副本。在JDK 8之前,这个内部Map是`ThreadLocal.ThreadLocalMap`,而从JDK 8开始,改为了`...

    ThreadLocal的几种误区

    当线程使用ThreadLocal时,它会查找或创建属于该线程的变量实例,而不是所有线程共享一个实例。 误区二:ThreadLocal与每个session相对应 在Java Web编程中,ThreadLocal与HTTP Session的概念混淆是常见的误解。...

    ThreadLocal原理及在多层架构中的应用

    - **难以调试**:由于ThreadLocal的隐式性,有时可能会导致难以发现的问题,特别是当线程池中的线程复用时。 ### 4. 使用注意事项 - 使用完毕后,应调用`remove()`方法清除ThreadLocal变量,防止内存泄漏。 - 尽量...

    2、导致JVM内存泄露的ThreadLocal详解

    1. **线程未正确销毁**:如果线程执行完毕后没有正确销毁或者线程池中线程长期存活,而`ThreadLocal`对象又未能及时清除,那么线程内的`ThreadLocalMap`将会持续占用内存,进而可能导致内存泄漏。 2. **...

    day18 10.使用ThreadLocal来解决问题

    ThreadLocal维护了一个线程局部存储的映射表,其中键是ThreadLocal实例,值是存储的变量副本。每个线程都有自己的ThreadLocalMap,当创建新的ThreadLocal实例时,如果没有为当前线程创建过这个映射表,那么就会为...

    ThreadLocal

    3. **避免同步**: 如果一个类的实例可能被多个线程同时访问,且每个线程需要有自己的实例状态,那么可以使用ThreadLocal来避免同步代码块的使用。 然而,使用ThreadLocal也需要注意一些潜在的问题: 1. **内存泄漏...

    ThreadLocal原理及在多层架构中的应用.pdf

    这样,即使在线程池环境下,每次任务执行时使用的就是线程私有的变量,不会产生线程安全问题。 在Java中,一个无状态的Bean(比如只有方法没有实例变量的类)是线程安全的,因为它不存储任何线程共享的状态。而有...

    详解Spring Cloud中Hystrix 线程隔离导致ThreadLocal数据丢失

    本文详解了Spring Cloud中Hystrix线程隔离导致ThreadLocal数据丢失的问题,并通过实例代码演示了该问题的出现原因和解决方法。 知识点1:Hystrix线程隔离 Hystrix是Spring Cloud中的一种断路器实现,用于防止服务...

    ThreadLocal内存泄露分析

    1. **忘记移除ThreadLocal引用**:当不再需要使用ThreadLocal时,如果没有调用`remove()`方法将其从当前线程的ThreadLocalMap中移除,那么这个ThreadLocal实例就会成为“僵尸”,因为它仍然保留在ThreadLocalMap中,...

    C#.NET多线程实例6个(包括多线程基本使用,多线程互斥等全部多线程使用实例),可直接运行

    9. **线程局部存储**:`ThreadLocal&lt;T&gt;`类允许在线程中创建局部变量,每个线程拥有自己的副本,互不影响。 10. **线程优先级**:虽然可以设置线程优先级,但不推荐频繁使用,因为操作系统调度策略可能使得高优先级...

    InheritableThreadLocal & ThreadLocal

    当我们创建一个ThreadLocal实例时,实际上是创建了一个全局的键值对存储,这个存储空间与线程相关联,每个线程有自己的独立副本,即使多个线程同时访问同一个ThreadLocal变量,也不会相互干扰。 二、...

    Java单线程ThreadLocal串值问题解决方案

    在Java中,ThreadLocal可以通过ThreadLocal类的实例来实现线程间隔离的变量访问。例如,在示例代码中,我们使用了ThreadLocal&lt;String&gt; currentUid = ThreadLocal.withInitial(() -&gt; null);来定义一个ThreadLocal变量...

    Android 中 ThreadLocal使用示例

    在Android开发中,ThreadLocal是一个非常重要的工具类,它提供了线程局部变量的存储机制。ThreadLocal类允许我们在多线程环境下为每...在实际开发中,我们可以结合线程池、Handler等机制,充分发挥ThreadLocal的作用。

    8个案例详解教会你ThreadLocal.docx

    而 `ThreadLocal` 变量则是在每个线程内部维护独立的实例,无需担心线程安全问题。 2. **存储位置** - `ThreadLocal` 变量存储在每个线程的 `ThreadLocalMap` 中,这个映射表是 `Thread` 类的一个内部类,因此每个...

    Java面试 spring知识点 线程池 面试题

    Bean工厂是Spring中最基本的容器,它负责实例化、配置和管理Bean。而ApplicationContext则是在Bean工厂的基础上扩展,提供了更多的企业级功能,如资源加载、国际化支持等。理解Bean的生命周期也是关键,包括初始化、...

    java核心知识点学习----多线程间的数据共享和对象独立,ThreadLocal详解.pdf

    在上述代码中,创建了一个ThreadLocal实例,然后在线程的run()方法中设置值,每个线程设置的数据只对自己可见,不会影响其他线程。这样既实现了数据共享(所有线程可以访问到ThreadLocal),又确保了对象独立(每个...

    java多线程编程实例_Source

    实例中可能涵盖常见线程安全问题,如数据竞争、死锁、活锁和饥饿,以及如何通过使用volatile、Atomic变量、线程局部变量(ThreadLocal)等手段来解决这些问题。 六、线程中断与异常处理 Java的Thread类提供了...

    深入理解高并发编程-Java线程池核心技术

    为了解决这一问题,我们可以使用线程局部变量(ThreadLocal)或者在每次使用时实例化新的SimpleDateFormat对象,避免在多线程环境下共享同一实例。 线程池的引入是为了克服直接创建线程的弊端,如线程创建和销毁的...

Global site tag (gtag.js) - Google Analytics