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
    来源:掘金
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    http2
    JMH java基准测试
    java 线程池
    线程中断
    mybatis
    JDBC 线程安全 数据库连接池
    mysql string 列类型
    剖析nsq消息队列目录
    go微服务框架go-micro深度学习-目录
    详说tcp粘包和半包
  • 原文地址:https://www.cnblogs.com/frankcui/p/15262085.html
Copyright © 2011-2022 走看看