- 是轻量级的进程,线程的创建和切换成本比进程低
- 同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间,文件描述符和信号处理等等
- 是操作系统能够进行运算调度的最小单位
- java程序至少有一个线程main,main线程由JVM创建
- 可以充分利用多处理器核心
- 更快的响应时间,可以将数据一致性要求不强的工作交给别的线程做
- 更好的编程模型,例如可以使用生产者消费者模型进行解耦
cpu通过时间分片来执行任务,多个线程在cpu上争抢时间片执行,线程切换需要保存一些状态,再次切换回去需要恢复状态,此为上下文切换成本。
因此并不是线程越多越快,频繁的切换会损失性能
减少上下文切换的方法:
- 无锁并发编程:例如把一堆数据分为几块,交给不同线程执行,避免用锁
- 使用CAS算法:用自旋不用锁可以减少线程竞争切换,但是可能会更加耗cpu
- 使用最少的线程
- 使用协程:在一个线程里执行多个任务
死锁就是线程之间因争夺资源处理不当出现的相互等待现象
避免死锁的方法:
- 避免一个线程同时获取多个锁
- 避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源
- 尝试使用定时锁,使用lock.tryLock(timeout)来替代使用内部锁机制
- 对于数据库锁,加锁和解锁必须在一个数据库连接里,否则会出现解锁失败的情况
程序的执行需要资源,比如数据库连接、带宽,可能会由于资源的限制,多个线程并不是并发,而是串行,不仅无优势,反而带来不必要的上下文切换损耗
常见资源限制
- 硬件资源限制
- 带宽
- 磁盘读写速度
- cpu处理速度
- 软件资源限制
- 数据库连接数
- socket连接数
应对资源限制
- 集群化,增加资源
- 根据不同的资源限制调整程序的并发度,找到瓶颈,把瓶颈资源搞多一些,或者根据这个瓶颈调整线程数