JAVA 线程编程 ----为什么要用多线程(Why Use Multiple Thread)

许多情况下,在一个程序中使用多线程是有益处的。下面是一些深度的观察,为什么是有好处的。

与用户的更好交互(Better Interaction with the User)
如果只有一个线程,那一个程序在同一时刻只能做一件事情。以字处理程序为例,当第一个文档正在格式化和排队打印时,可以打开第二个文档那该多好啊。在一些早前的字处理软件中,当用户想要打印一个文档时,如果该文档正在准备并发送给打印机时,他只好等待。(即,用户不能在等待打印同时,用该软件做其他事情)现代字处理软件开发利用了多线程可以同时做两件事情。在单处理器(one-processor)的系统中,可通过操作系统在两个任务之间快速的来回切换来模拟此场景,以此来实现更好的与用户交互。

从微处理器的角度来看,即使是最快的打字员在按键之间也花费了巨大的时间。在这些大量的时间间隙,处理器可以处理其他任务。当另外一个线程停止了其他工作时,如果一个线程总在等待给用户的动作一个快速的响应,比如点击鼠标或按键,用户将会从系统中感觉到更好的响应。

模拟同时进行的活动(Simulation of Simultaneous Activities)

即使只有一个处理器,Java中的线程好像也是并发运行。处理器运行每个线程一小段时间,并在线程之间切换来模拟并发执行。这使得每个线程看似都独立拥有自己的处理器。利用这一特性,你可以使得多个任务好像正在同时发生。实际上是在上下文(Context)切换到另外线程之前,每个线程只运行很短时间。

开发利用多处理器(Exploitation of Multiple Processors)
一些机器中有多个处理器。如果当前的操作系统和JVM的实现开发利用了多处理器,多线程的Java程序能实现真正的线程并发执行。而Java程序不需要修改,因为它已经用了线程。就像这些线程同时运行在不同的处理器上一样,它只能运行得更快。

当等待慢的I/O操作时,可以做其他事情(Do Other Things While Waiting for Slow IO Operations)

相对于处理器中的代码执行速度,对磁盘的输入输出操作,特别是跨网络的操作,速度相对来说是慢的。结果为了等待完成,读写操作可能被阻塞(block)相当长时间。

在java.io包中,类InputStream有一个read()方法会被阻塞,直到从流(stream)中读一个字节或者抛出一个IOException异常。当等待流上字节的到来时,执行该方法的线程不能做其他事情。如果创建了多线程,当某线程被阻塞后,其他线程就可以完成其他活动。

例如,你有一个包含多个TextField组件的Java Applet程序,下图显示了两个线程是如何给用户提供更好的用户交互的伪代码。第一个线程是GUI事件线程,该线程大部分时间都在waiForNextEvent()方法中被阻塞。第二个线程是工作线程,它初始化为阻塞状态,在waitUntilSignalled()方法中等待一个继续工作的信号。当所有的TextField组件生成之后,用户点击了传输数据按钮。GUI事件线程被解除阻塞,进入deliverEventToListenser()方法,随又调用actionPerformed()方法,该方法给工作线程一个信号,然后立即返回到waitForNextEvent()方法。工作线程被解除阻塞,离开了waitUntilSignaled()方法,进入gatherDataAndTransmit()方法。工作线程收集用户输入的数据,进行传输,当等待服务器确认信息时又被阻塞。当读取确认信息之后,工作线程返回waitUntilSignalled()方法。

简化对象建模(Simplify Object Modeling)

在构建一个系统,需要对系统按照面向对象进行分析,这可能要求某些对象以线程方式运行。这类对象可被认为是主动的(active),与消极(passive)相对应。一个消极对象只有当该对象的方法被调用是才能修改其内部状态。一个积极对象可以自动改变内部的状态。

   例如,构建一个数字时钟的图形化组件,该组件显示当前系统小时和分钟。每隔60秒,组件中的分钟将会改变。最简单的设计是在时钟组件内创建一个线程,该线程专门负责修改数字。如果不这样的话,就需要一个外部线程,它除了完成其它任务外,还需要不断地监测是否需要更新数字。如果这个外部线程需要从InputStream读取数据,此时就会被阻塞,如果它等待一个字节的时间超过一分钟,那又该怎如何呢?所以在这里,我们可以利用多线程编程的优势来简化问题的解决。











你可能感兴趣的:(java,多线程,thread,编程,工作)