当前位置:编程学习 > JAVA >>

Java——多线程编程[1]

用多线程分解任务进行并发处理
1. 从单线程任务到多线程任务的转换
本章我们将处理两种类型的数据,一种是IO密集型任务,另一中是计算密集型任务。
      分而治之
如果我们有数百只股票需要处理,你可以一只只股票地线性处理,不过那可能是一种很愚蠢的行为。为了使我们的程序能够更快的运行,我们可以把这个任务分成多个任务并行地处理。不过我们也不能分成太多个线程,因为计算机的资源是有限的,开辟线程会消耗额外的线程资源。
      决定线程数量
对于一个大型程序,我们可以开辟的线程数量至少等于运行机器的cpu内核数量。java程序里我们可以通过下面的一行代码得到这个数量:
  [java]
<SPAN style="WHITE-SPACE: pre"> </SPAN><SPAN style="FONT-SIZE: 14px">Runtime.getRuntime().availableProcessors();</SPAN> 

 Runtime.getRuntime().availableProcessors(); 所以最小线程数量即时cpu内核数量。如果所有的任务都是计算密集型的,这个最小线程数量就是我们需要的线程数。开辟更多的线程只会影响程序的性能,因为线程之间的切换工作,会消耗额外的资源。如果任务是IO密集型的任务,我们可以开辟更多的线程执行任务。当一个任务执行IO操作的时候,线程将会被阻塞,处理器立刻会切换到另外一个合适的线程去执行。如果我们只拥有与内核数量一样多的线程,即使我们有任务要执行,他们也不能执行,因为处理器没有可以用来调度的线程。
        如果线程有50%的时间被阻塞,线程的数量就应该是内核数量的2倍。如果更少的比例被阻塞,那么它们就是计算密集型的,则需要开辟较少的线程。如果有更多的时间被阻塞,那么就是IO密集型的程序,则可以开辟更多的线程。于是我们可以得到下面的线程数量计算公式:
线程数量=内核数量 / (1 - 阻塞率)
我们可以通过相应的分析工具或者java的management包来得到阻塞率的数值。
      决定分隔的任务数量
我们已经知道了如何决定线程数量,现在我们来讨论下把任务分隔成多少子任务是最合适的,每个子任务并发执行。于是,我们第一个想到的是,分配与线程数量一样多的子任务是最合适的,这看起来很合适但其实是不够的,我们忽略了具体子任务的性质。
例如,在股票处理的程序上,把分成与线程数量一样多的子任务就足够了。
        但是对于,获取素数的程序,这样就是有问题的。因为偶数是很容易就处理完,大的素数比小的素数会花费更多的时间处理。把所有的数根据从大到小分隔成与线程数量一样多的部分进行处理并不能帮我们提升多少性能。一些线程会比另外一些线程更快的执行完,这样的话内核就不能有效的利用。
换言之,如果我们想这样分隔,我们必须花费很多精力去恰当的分隔这些数据到这些任务来处理,以至于这些任务都能有同等的负载均衡。然而这样做的话就会存在两个问题:1,这样的分隔的确很难。2,这种分隔在程序里面也比较复杂。
事实证明,让每个cpu内核保持忙碌比想办法让每个部分的负担一样更加有效。在处理器的角度来看,当仍然有任务需要处理的时候,没有处理器空闲着。所以,与其想办法把任务分成负载相等的子任务,不如分隔比线程数量更多的线程让处理器保持忙碌。


2. 获取高效并发性能的方法
一方面,我们要确保并发的一致性和准确性;另一方面,我们要确保在给定的机器上得到更好的性能。下面,我们来探寻满足这两者的方法。
只要我们能完全的消除共享可变状态变量,就可以很容易地避免条件竞争或者一致性问题。当多个线程不竞争地去获得可变数据,变量就不会有可变性问题。我们也不用担心控制线程的执行顺序。
如果可能的话,就提供多个线程共享的不可变变量。否则,遵循孤立可变性原则,确保只有一个线程能够访问这个可变变量。我们现在不讨论同步线程状态的情况,我们暂时只确保只有一个线程可以访问可变的变量。
我们创建多少线程并且将任务分成多少份子任务将会影响并发程序的性能。首先,为了利用并发性所带来的好处,我们必须能够将任务划分成子任务。如果一个问题有一个不可被分割的重要部分,那么这个程序不能通过引入并发来获得更好的性能。如果任务是IO密集型的,或者有大量的IO操作,那么开辟更多的线程将会带来性能上的提高。在这种情况下,开辟比cpu内核更多的线程将会对程序的性能很有益处。对于一个计算密集型的任务,开辟比cpu内核多的线程其实并不利于性能的提高。然而,我们至少可以通过开辟与内核数量相等的性能来提高性能。
虽然开辟线程可以影响性能,但是这不是唯一的一种情况。通过分解任务,也可以影响性能。

补充:软件开发 , Java ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,