解决方案 »

  1.   

    ThreadPoolManager.dbShortSchedule(new InsetDataTask(
    MongoDbManager.METADATA_COLLECTION, meatList), 0);
    这句是干什么的? 另启一线程? 做什么?
      

  2.   

    参考一下下面这些结论:
    书上是这么说的:
    synchronized 关键字的作用是由系统自动给被synchronized修饰的方法或代码块加锁,使被修饰的代码在同一时间只能被一个线程访问。我的疑问:难道同一时间,能被两个线程访问,有鬼了。CPU也只有在同一时间被一个资源访问,当然不是说多核的CPU这个其实是涉及到操作系统内核的调度问题了,假如一个线程执行到这个函数的一半的时候就被操作系统中断了(也就是此线程的时间片已经用完了或者被其它优先级高的进程/线程抢占了),轮到其它线程开始运行了,假如其它线程也要执行到这个函数,这种情况下就是所谓的“两个线程同时执行一段代码或者访问同一资源”,至于“同一时间,能被两个线程访问”的说法其实只是从用户的角度来说而已,在操作系统内核层次的话,在单CPU情况下,严格来说这种说法是不准确的,但是在用户层,为了让用户更好的理解这种同步的机制,一般都是采用这样的说法的了 
      

  3.   

    线程安全的队列,元素是list,定时器每隔10秒存储一个list。
      

  4.   

    你这样做当然是肯定有问题的.
             synchronized (meatList) {
                    /**线程储存数据*/
                    ThreadPoolManager.dbShortSchedule(new InsetDataTask(
                            MongoDbManager.METADATA_COLLECTION, meatList), 0);
                }如果是多个线程同时调用这个saveDataToDbMeta方法,你这段只是保证了dbShortSchedule方法每一次只有一个线程执行.可是问题是下面一句“meatList.clear();”,那么基本上有可能在dbShortSchedule方法执行完之前已经就把meatList数据清空了,你的InsetDataTask再读的时候已经是一个空的Map了.这里你要做的是改成如下,创建一个副本给创建的任务用.
    ThreadPoolManager.dbShortSchedule(new InsetDataTask(
                            MongoDbManager.METADATA_COLLECTION, new HashMap(meatList)), 0);
    这样你的meatList如何改变,也不会影响InsetDataTask中拿到数据.