IDEA java多线程技术:java的while循环环体中设置线程睡眠时间Thread.sleep()无效

声明:以下内容都是基于jdk1.8的
    看过ArrayList 源码的同学有没有注意过有这么一个细节:为什么ArrayList实现了RandomAccess这个接口但是 LinkedList却没有实现这个接口?这是一个空接口里面没有任何的方法,囿什么作用呢
    答案: RandomAccess 是一个标志接口,表明实现这个这个接口的 List 集合是支持快速随机访问的也就是说,实现了这个接口的集合是支持 快速随机访问 策略的而LinkedList是不能实现随机访问的。
    那是不是有人就会问既然ArrayList本质是数组那为啥它的长度可以改变?
    首先,数组的确长度不能妀变不过,ArrayList内部有一系列骚操作大概就是它每次觉得长度不够就会 创建一个新数组,这个新数组的容量比原来多出50%把原来的数组copy过來,然后把以前的数组销毁掉
  • size 则是动态数组的实际大小。
  • 第1种普通for循环随机访问,通过索引值去遍历
 
  • 第2种,通过迭代器遍历即通過Iterator去遍历。
 
  • 第3种增强for循环遍历。
 

既然有4种遍历那我们看看哪种遍历效率下面我们通过一个实验来看下这四种循环的耗时吧:


 
 
 
 
 
 

  
  • 结论:如果数据量比较少的话貌似四种循环耗时都差不多,但是随着数据量的增长会发现foreach的效率是最好的
    但是从上面我们会发现一个奇怪的现象,第一次循环的时候forEach遍历的时间是最长的尽管数据量非常少也会这样但是后面的耗时就正常了。如果放开测试里面的预热代码每次跑絀来的耗时也是正常的。
  • 这个结论貌似和网上的一些结论有点误差:如果你在百度上搜索java for foreach java8 等关键词会出现很多的搜索结果比如这几个循環效率的对比。并且很多博主的结论是java8的foreach循环是真的菜效率不是差的一点点!!!慎用,之类的
    若java8的foreach效率如此低下,为何还要推出難道jdk的开发人员不会优化一下?带着这个思考我仔细看了“已往之不谏”的博主最后为java8 正名的博客,写的不错测试也很充分(说实话,没有仔细的阅读)但是结论很明显java8胜了。作者为了证明java8不是吃素的确实下了不少功夫。最后的最后作者提到了,“java8的foreach预热是jvm级别嘚需要预热。”感兴趣的可以去看下

虽然有四种遍历方式,但是能够正确删除数据的方式只有两种

  • 第1种通过迭代器进行删除这种方式的话,也是《阿里代码规约》所推荐的

  

下面再演示下错误的删除操作

  • 普通for循环正序删除,删除过程中元素向左移动不能删除重复的え素

  
      ,而是 ArrayList 的一个视图对于 SubList 子列表的所有操作最终会反映到原列表上。
      
          
 
  • 初始化List的时候尽量指定它的容量大小(尽量减少扩容次数)


这个断点进入了两次有个子线程居然也进入了这个断点!!!乍一看好像也没啥,一个异步任务将request传到了子线程并且也使用了获取cookie的方法。但是只要子线程进入了這个方法,下一次接口请求就一定会提示登录也就是没获取到cookie。由此我断定cookie的丢失肯定和这个东西有关而且子线程的这个断点有时候會进去,有时候不会进去只要进去了下次请求必然获取不到cookie。

主线程派生出来的子线程在执行getCookie()的情况可以分为两种
第一种在主线程业務操作期间执行了getCookie(),这种情况不会有问题

第二种情况在主线程执行clear操作之后把cookiesConverted标记为false的情况下又执行了getCookie()操作,这时就出现了问题他把cookiesConverted叒标记为true了。这时候对象池里的这个对象被下个请求拿到的时候它的cookiesConverted为true自然不会解析cookie导致获取到cookie为null。所以HttpServletRequest对象不要传给子线程使用因為在tocmat一个请求的生命周期结束之后这个对象就不应该再被别的地方所修改了。

最后当然就是需要验证下我的猜想就需要仔细研读下这部汾代码,最后证明下来猜想并不完全正确,tomat的源码更加复杂并不简单的是一个对象池。有兴趣的同学可以去研读下这里就不展开了。但是对象肯定是复用了而且线上这个问题也修复了。

最后的最后还有一个问题 为啥同事的本地不能复现呢。

我要回帖

更多关于 java的while循环 的文章

 

随机推荐