zoukankan      html  css  js  c++  java
  • Java 多线程

    频繁创建新线程有什么缺点?

    1.不受控风险

    系统资源有限,每个人针对不同业务都可以手动创建线程,并且创建标准不一样(比如线程没有名字)。当系统运行起来,所有线程都在疯狂抢占资源,无组织无纪律,内存很容易被无情榨干耗尽。

    另外,过多的线程自然也会引起上下文切换的开销。

    2.频繁创建开销大

    new Thread() 在操作系统层面并没有创建新的线程;

    真正转换为操作系统层面创建一个线程,还要调用操作系统内核的API,然后操作系统要为该线程分配一系列的资源。

    2.1 new Object() 过程

    Object obj = new Object();

    当我需要【对象】时,我就会给自己 new 一个(不知你是否和我一样),这个过程你应该很熟悉了:

    1. 分配一块内存 M
    2. 在内存 M 上初始化该对象
    3. 将内存 M 的地址赋值给引用变量 obj

    就是这么简单

    2.2 new Thread() 过程

    上面已经提到了,创建一个线程还要调用操作系统内核API。为了更好的理解创建并启动一个线程的开销,我们需要看看 JVM 在背后帮我们做了哪些事情:

    1. 它为一个线程栈分配内存,该栈为每个线程方法调用保存一个栈帧
    2. 每一栈帧由一个局部变量数组、返回值、操作数堆栈和常量池组成
    3. 一些支持本机方法的 jvm 也会分配一个本机堆栈
    4. 每个线程获得一个程序计数器,告诉它当前处理器执行的指令是什么
    5. 系统创建一个与Java线程对应的本机线程
    6. 将与线程相关的描述符添加到JVM内部数据结构中
    7. 线程共享堆和方法区域

    这段描述稍稍有点抽象,用数据来说明创建一个线程(即便不干什么)需要多大空间呢?答案是大约 1M 左右

     
    java -XX:+UnlockDiagnosticVMOptions -XX:NativeMemoryTracking=summary -XX:+PrintNMTStatistics -version

    上图是我用 Java8 的测试结果,19个线程,预留和提交的大概都是19000+KB,平均每个线程大概需要 1M 左右的大小(Java11的结果完全不同,这个大家自行测试吧)

    相信到这里你已经明白了,对于性能要求严苛的现在,频繁手动创建/销毁线程的代价是非常巨大的,解决方案自然也是你知道的线程池了

    参考文献

    作者:日拱一兵
    链接:https://juejin.cn/post/6844904134324256775
    来源:掘金
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    sqlserver中判断表或临时表是否存在
    Delphi 简单方法搜索定位TreeView项
    hdu 2010 水仙花数
    hdu 1061 Rightmost Digit
    hdu 2041 超级楼梯
    hdu 2012 素数判定
    hdu 1425 sort
    hdu 1071 The area
    hdu 1005 Number Sequence
    hdu 1021 Fibonacci Again
  • 原文地址:https://www.cnblogs.com/frankcui/p/15262085.html
Copyright © 2011-2022 走看看