第七十二条 不要依赖于线程调度器

当有多个线程可以运行时,由线程调度器决定哪些线程将会运行,以及运行多长时间。任何一个合理的操作系统在做出这样的决定时,都会努力做到公正,但是所采用的策略却相差无几。因此,编写良好的程序不应该依赖于这种策略的细节。任何依赖于线程调度器来达到正确性或者性能要求的程序,很有可能都是不可移植的。我们一般是需要把功能单独模块化,保持独立,超级解耦,随时都能被拎出来,被其他项目复用。

要编写健壮的、响应良好的、可移植的多线程应用程序,最好的办法是确保可运行线程的平均数量稍微小于多余处理器的数量。这使得线程调度器没有更多的选择:它只需要运行这些可运行的线程,直到他们不再可运行为止。即使在根本不同的线程调度算法下,这些程序的行为也不会有很大的变化。注意可运行线程的数量并不等于线程的总数量,在等待的线程并不是可运行的,处理完一条运行线程,有空额余出后,马上让一条等待线程变为运行线程,依次循环。

保持可运行线程数量尽可能少的主要方法是,让每个线程做些有意义的工作,如果线程没有在做有意义的工作,就不应该运行。根据Executor Framework,这意味着适当地规定了线程池的大小,并且使任务保持适当地小,彼此独立,任务处理数据的量不能太小,否则没必要单独开线程,可以适当的把数据合并处理,否则分配的开销也会影响到性能;线程不能一直出于等待的状态,也不能反复的检查一个对象,直到达到某种临界值,这样会极大影响效率。

CountDownLatch 是通过阻塞当前线程,线程会进入了一个死循环当中,在这个死循环里面,会不断的进行判断值,但这个死循环并不是一刻不停的,而是到后面会执行LockSupport.park(this);,来禁用当前线程的。如果我们想自定义一个阻塞线程,单纯的用java中的for循环不停的去检查对象,可以想象,一秒中for循环会执行多少遍,这会严重消耗性能,得不偿失。系统有现成的,我们就没必要再去造轮子了。

线程的优先级是由等级决定的,如果想让某条线程尽量的先执行,一个是提高线程的等级,另外一个就是尽量早的运行线程。使用线程池的话,如果核心线程和等待线程不够用的话,我们应尽量调整线程池的策略,而不是一味的开线程。可以通过合并、延迟等方法来达到目的。我们应该遵循逻辑的正确性,而不是完全依赖线程调度器。不要依赖于 Thread.yield 来进行线程优先。

猜你喜欢

转载自blog.csdn.net/Deaht_Huimie/article/details/84946328
今日推荐