多个线程可运行时,
- 线程调度器决定哪些线程将会被运行、以及运行多长时间
- 任何操作系统在处理该问题时,会 尽力做到公正,但是策略却大相径庭
- 编写良好的程序不要依赖这种策略细节,否则程序将不可移植
要编写健壮、可移植、响应良好的多线程程序,线程数量不要明显多于处理器核数
让每个线程做有意义的工作,
- 不要处在不必要的可运行状态
- 规定线程池大小、不宜太小,否则线程分配开销影响性能
- 任务保持适当的小,保持独立
线程不应该一直处于一个 (busy - wait)的状态
- 反复检查一个共享对象
- 极端例子,countDownLatch 的不正当重新实现:
- await 方法死循环等待
如果某个程序不能工作,是由于无法获得足够的cpu时间,
- 不要企图使用 Thread.yield
- 因为在jvm 中,yield的表现差别很大
- 更好的策略是减少可并发运行线程数量
调整线程优先级也是java平台最不可移植的特征
- 采用次方法解决活性问题不合理,因为依然会再次出现
Thread.sleep(1) 在测试期间增加程序并发性,代替了Thread.yield
- Thread.sleep(0) 会直接返回,请不要使用
总结:
- 不要让程序的正确性依赖于调度器
- 否则,程序不健壮、可移植性差
- 作为推论,不要使用Thread.yield或线程优先级
- 这些指令仅仅对调度器做些暗示
- 优先级能够提高一个能够正常工作的程序的服务质量
- 但不能“修复” 原本不能工作的程序