java的多线程是怎么提高效率的呢?

时间:2022-10-11 10:41:49
最近一直有个问题困扰我,希望那位大哥帮我解释一下。

就是pc运行时把一个任务分为一个个时间片运行的,但是运用多线程就可以提高执行效率,但是总的时间片是一定的,时间片

也没有减少,那么多线程是怎么实现高效率的呢,换句话说,多进程是怎么实现并发处理的,多线程就是多进程的一个缩小

版,只是占用的资源较少,那么多进程是怎么实现的呢,是基于一种什么机制呢 。呵呵,问题可能提的不清楚,大家理解多

少,就解释多少吧。呵呵,麻烦大家了。

32 个解决方案

#1


科班该学《操作系统》那门课的吧?!

#2


就好比你要煮饭和扫地两件事情

你是一直等到饭煮熟才扫地呢还是等待饭煮熟的时间去扫地呢,显然后者效率高

cpu也一样,没有密集型的计算,大部分时间cpu都是处于等待中,多线程就可以利用这些空闲的资源

#3


多线程就是多进程的一个缩小

版,只是占用的资源较少


-----------------

上面的说法是错误的
关于这个可以看一本书叫《java线程》,网上有英文版的,《操作系统》那么课也会讲到的
进程和线程最大的区别是线程之间可以共享资源,如java中的堆和方法区。多个进程之间则不能共享这些资源

#4


单核CPU里,多线程不能提高程序的效率,但是可以改善用户体验。
有N个核的CPU,最多使用N个线程可以提高效率,在于N个线程只会降低程序的效率。
但是与多线程牺牲的效率相比,用户体验更重要。

#5


引用 2 楼 ticmy 的回复:
就好比你要煮饭和扫地两件事情

你是一直等到饭煮熟才扫地呢还是等待饭煮熟的时间去扫地呢,显然后者效率高

cpu也一样,没有密集型的计算,大部分时间cpu都是处于等待中,多线程就可以利用这些空闲的资源

不一样,CPU不是同时做几件事,CPU中是按任务顺序执行的,单核CPU同时只能做一件事。

#6


并行跟并发的关系

但是这个比喻本身没问题,这个比喻中,人是cpu,煮饭可能是某个阻塞型的IO操作


引用 5 楼 inhibitory 的回复:
引用 2 楼 ticmy 的回复:

就好比你要煮饭和扫地两件事情

你是一直等到饭煮熟才扫地呢还是等待饭煮熟的时间去扫地呢,显然后者效率高

cpu也一样,没有密集型的计算,大部分时间cpu都是处于等待中,多线程就可以利用这些空闲的资源

不一样,CPU不是同时做几件事,CPU中是按任务顺序执行的,单核CPU同时只能做一件事。

#7


引用 5 楼 inhibitory 的回复:
引用 2 楼 ticmy 的回复:

就好比你要煮饭和扫地两件事情

你是一直等到饭煮熟才扫地呢还是等待饭煮熟的时间去扫地呢,显然后者效率高

cpu也一样,没有密集型的计算,大部分时间cpu都是处于等待中,多线程就可以利用这些空闲的资源

不一样,CPU不是同时做几件事,CPU中是按任务顺序执行的,单核CPU同时只能做一件事。


单核CPU可以同时做多件事,只不过他是先执行一件事情的一点点,然后停下,再去执行下一件事情的一点点、
是这样循环执行的、因为CPU的速度非常快,我们是感觉不出来的

#8


引用 6 楼 ticmy 的回复:
并行跟并发的关系

但是这个比喻本身没问题,这个比喻中,人是cpu,煮饭可能是某个阻塞型的IO操作


引用 5 楼 inhibitory 的回复:

引用 2 楼 ticmy 的回复:

就好比你要煮饭和扫地两件事情

你是一直等到饭煮熟才扫地呢还是等待饭煮熟的时间去扫地呢,显然后者效率高

cpu也一样,没有密集型的计算,大部分时间cpu都是处于等待中,多线程就可以……

嘿嘿,忘了IO

#9


谢谢楼上的回复,但是有时多线程可以比单线程的效率高达10倍甚至100倍以上,但是计算机在一个时间片里

只能进行一种操作,虽说运用了多线程,但是任务的总的时间片没有减少啊,那么他们是怎么进行处理的呢,

才可以产生10倍甚至100倍的高效率的呢,所以说计算机在一个时间片只能进行一种操作,而且任务总的时间

片没有减少,那么他们是怎么实现高效率的呢。呵呵,有点钻死牛角了,希望哪位帮我解释一下。

可能我关于线程和进程的关系的理解有些错误,谢谢楼上的指证。

#10


"但是有时多线程可以比单线程的效率高达10倍甚至100倍以上"
@: 这是哪个害人精的理论?

#11


呵呵,我知道多线程的原理是利用cpu在进行IO操作的空闲时间来进行操作,提高了cpu的利用效率,但是整个

任务的时间片总数并没有减少啊,单核的多线程提高的效率没有双核的效率高,双核使一个计算机可以在一个

时间片进行两件事情,但是多线程在单核情况下应该也是可以提高效率的啊,这个不是单双核的原因吧,它是

基于一种什么运行机制呢?哪位高手帮忙解答,在这谢过了。

#12


"但是有时多线程可以比单线程的效率高达10倍甚至100倍以上"
@: 这是哪个害人精的理论? 
 


呵呵,在某些特殊情况下这个比例是可以实现的。

#13


很多时间片是浪费的,所以你经常看到CPU使用率10%以下哦

要是cpu利用率一直是100%,多线程也未必能提高多少效率了

引用 9 楼 genglukuan 的回复:
谢谢楼上的回复,但是有时多线程可以比单线程的效率高达10倍甚至100倍以上,但是计算机在一个时间片里

只能进行一种操作,虽说运用了多线程,但是任务的总的时间片没有减少啊,那么他们是怎么进行处理的呢,

才可以产生10倍甚至100倍的高效率的呢,所以说计算机在一个时间片只能进行一种操作,而且任务总的时间

片没有减少,那么他们是怎么实现高效率的呢。呵呵,有点钻死牛角了,希望哪位帮我解……

#14


呵呵, 就像单进程和多进程一样,他们的更替总是有一定的趋势必然性,多线程是凭借什么优势站住脚的呢?

#15


前面我已经说过线程和进程最大的不同了,就是共享资源的问题

引用 14 楼 genglukuan 的回复:
呵呵, 就像单进程和多进程一样,他们的更替总是有一定的趋势必然性,多线程是凭借什么优势站住脚的呢?

#16


呵呵,这位大哥,我可能没有表达清楚,我问的是多线程相对单线程有什么优势?

#17


1.3 Why Threads?
The notion of threading is so ingrained in Java that it's almost impossible to write even the simplest programs in Java without creating and using threads. And many of the classes in the Java API are already threaded, so often you are using multiple threads without realizing it.

Historically, threading was first exploited to make certain programs easier to write: if a program can be split into separate tasks, it's often easier to program the algorithm as separate tasks or threads. Programs that fall into this category are typically specialized and deal with multiple independent tasks. The relative rareness of these types of programs makes threading in this category a specialized skill. Often, these programs were written as separate processes using operating system-dependent communication tools such as signals and shared memory spaces to communicate between processes. This approach increased system complexity.

The popularity of threading increased when graphical interfaces became the standard for desktop computers because the threading system allowed the user to perceive better program performance. The introduction of threads into these platforms didn't make the programs any faster, but it created an illusion of faster performance for the user, who now had a dedicated thread to service input or display output.

In the 1990s, threaded programs began to exploit the growing number of computers with multiple processors. Programs that require a lot of CPU processing are natural candidates for this category since a calculation that requires one hour on a single-processor machine could (at least theoretically) run in half an hour on a two-processor machine or 15 minutes on a four-processor machine. All that is required is that the program be written to use multiple threads to perform the calculation.

Although computers with multiple processors have been around for a long time, we're now seeing these machines become cheap enough to be very widely available. The advent of less expensive machines with multiple processors, and of operating systems that provide programmers with thread libraries to exploit those processors, has made threaded programming a hot topic as developers move to extract every benefit from these machines. Until Java, much of the interest in threading centered on using threads to take advantage of multiple processors on a single machine.

However, threading in Java often has nothing at all to do with multiprocessor machines and their capabilities; in fact, the first Java virtual machines were unable to take advantage of multiple processors on a machine. Modern Java virtual machines no longer suffer from this limitation, and a multithreaded Java program takes advantage of all the CPUs available on its host machine. However, even if your Java program is destined to be run on a machine with a single CPU, threading is still very important.

One reason that threading is important in Java is that, until JDK 1.4, Java had no concept of asynchronous behavior for I/O. This meant that many of the programming techniques you've become accustomed to using in typical programs were not applicable in Java; instead, until recently, Java programmers had to use threading techniques to handle asynchronous behavior. Another reason is the graphical nature of Java; since the beginning, Java was intended to be used in browsers, and it is used widely in environments with graphical user interfaces. Programmers need to understand threads merely to be able to use the asynchronous nature of the GUI library.

This is not to say there aren't other times when threads are a handy programming technique in Java; certainly it's easy to use Java for a program that implements an algorithm that naturally lends itself to threading. And many Java programs implement multiple independent behaviors. The next few sections cover some of the circumstances in which Java threads are a needed component of the program — either directly using threads or using Java libraries that make heavy use of threads. Many of these circumstances are due to the need for asynchronous behavior or the elegance that threading lends to the program.

 

#18


1.3.1 Nonblocking I/O
In Java, as in most programming languages, when you try to get input from the user, you execute a read() method specifying the user's terminal (System.in in Java). When the program executes the read() method, the program typically waits until the user types at least one character before it continues and executes the next statement. This type of I/O is called blocking I/O : the program blocks until some data is available to satisfy the read() method.

This type of behavior is often undesirable. If you're reading data from a network socket, that data is often not available when you want to read it: the data may have been delayed in transit over the network, or you may be reading from a network server that sends data only periodically. If the program blocks when it tries to read from the socket, it's unable to do anything else until the data is actually available. If the program has a user interface that contains a button and the user presses the button while the program is executing the read() method, nothing happens: the program is unable to handle the mouse events and execute the event processing method associated with the button. This can be very frustrating for the user, who thinks the program has hung.

Traditionally, three techniques are available to handle this situation:




I/O Multiplexing

Developers often take all input sources and use a system call like select() to notify them when data is available from a particular source. This allows input to be handled much like an event from the user (in fact, many graphical toolkits use this method transparently to the developer, who simply registers a callback function that is called whenever data is available from a particular source).

Beginning with JDK 1.4, this feature is provided with the NIO library—a library that allows a programmer to deal with I/O in an asynchronous manner.




Polling

Polling allows a developer to test if data is available from a particular source. If data is available, the data can be read and processed: if it is not, the program can perform another task. Polling can be done either explicitly—with a system call like poll()—or, in some systems, by making the read( ) function return an indication that no data is immediately available.

Polling is also supported by the NIO library of JDK 1.4. In the traditional I/O library, there is only limited support for polling via the available() method of the FilterInputStream class. Unfortunately, this method does not have the rich semantics that polling typically has in most operating systems and is not recommended as a reliable technique to determine whether data is actually available.




Signals

A file descriptor representing the input source can often be set so that an asynchronous signal is delivered to the program when data is available on that input source. This signal interrupts the program, which processes the data and then returns to whatever task it had been doing. Java does not support this technique.

While the issue of blocking I/O can conceivably occur with any data source, it occurs most frequently with network sockets. If you're used to programming sockets, you've probably used one of these techniques to read from a socket, but perhaps not to write to one. Many developers, used to programming on a local area network (LAN), are vaguely aware that writing to a socket may also block, but it's a possibility that many of them ignore because it happens only under certain circumstances, such as a backlog in getting data onto the network. This backlog rarely happens on a fast LAN, but if you're using Java to program sockets over the Internet, the chances of this backlog happening are greatly increased, thus increasing the chance of blocking while attempting to write data onto the network. In Java, you may need two threads to handle the socket: one to read from the socket and one to write to it.

As a result, writing a program that uses I/O means either using multiple threads to handle traditional (blocking) I/O or using the NIO library (or both). The NIO library itself is very complex—much more complex than the thread library. Consequently, it is still often easier to set up a separate thread to read the data (using traditional I/O) from a blocking data source. This separate thread can block when data isn't available, and the other thread(s) in the Java program can process events from the user or perform other tasks.

On the other hand, there are many times when the added complexity of the NIO library is worthwhile and where the proliferation of threads required to process thousands of data sources would be untenable. But using the NIO library doesn't remove all threading complexities; that library has its own thread-related issues.

We examine the threading issues related to I/O in depth in Chapter 12.

#19


1.3.2 Alarms and Timers
Traditional operating systems typically provide some sort of timer or alarm call: the program sets the timer and continues processing. When the timer expires, the program receives some sort of asynchronous signal that notifies the program of the timer's expiration.

In early versions of Java, the programmer had to set up a separate thread to simulate a timer. That thread slept for the duration of a specified time interval and then notified other threads when the timer expired. As Java matured, multiple new classes that provide this functionality were added. These new classes use the exact same technique to provide the functionality, but they hide (at least some of) the threading details from the developer. For complete details on these timers, see Chapter 11.

#20


该回复于2011-01-10 11:30:59被版主删除

#21


那你买本书吧
http://item.taobao.com/item.htm?id=8589723859

第一章第三节

#22


不是,大哥,我一个问题不会我买本书,另一个问题不会我还买本书,几年以后我成开书店的了,大哥,帮帮

忙,大概解释一下是什么意思就行,在这谢过了。

#23


就算是单核CPU
排除进程优先级的话 开启多线程的话 也可以使进程获得更多的时间片 只是计算机整体的计算能力没有提高

#24


大概的意思就是:
多线程可以共享同一个java虚拟机实例中堆和方法区的信息
在有阻塞操作的时候(如blocking IO),可以改善用户体验,比如酷狗,你可以一边下载,一边修改其他歌曲的信息,如果是单线程的,在下载没完成的时候,界面就死在那,直到下载完成

#25


不过,如果做开发,这本书还是值得一看的

#26


大哥,谢谢你,我明天就结贴,今天再挂一天,看看大家还有什么高见。明天准时给分。

#27


引用 2 楼 ticmy 的回复:
就好比你要煮饭和扫地两件事情

你是一直等到饭煮熟才扫地呢还是等待饭煮熟的时间去扫地呢,显然后者效率高

cpu也一样,没有密集型的计算,大部分时间cpu都是处于等待中,多线程就可以利用这些空闲的资源

这个比喻很恰当,多线程用于阻塞并发,也就是有时间休息等待就可以用这个时间干别的事。

#28


目的就是尽量不让可用资源闲着

[img=http://c.rednet.cn/zt/edu/2010nhbaby/api/?vote&3904][/img]

#29


比如以个远程的请求,需要等待请求后的回复,如果请求的响应时间有点久,那么如果是单线程就卡住了,
多线程就继续做其他事情。

#30


LZ不要迷信多线程,单核CPU跑满时,开多少个线程都无法提高效率,还会因线程切换的原因,使效率下降。有阻塞机制的情况下,多线程比较有意义。

#31


使用多线程的一个原因是提高CPU利用率,另一个原因是可以更逼近的描述现实中的并发操作,有时候是有这种需求的。

#32


看看线程池啥的

#1


科班该学《操作系统》那门课的吧?!

#2


就好比你要煮饭和扫地两件事情

你是一直等到饭煮熟才扫地呢还是等待饭煮熟的时间去扫地呢,显然后者效率高

cpu也一样,没有密集型的计算,大部分时间cpu都是处于等待中,多线程就可以利用这些空闲的资源

#3


多线程就是多进程的一个缩小

版,只是占用的资源较少


-----------------

上面的说法是错误的
关于这个可以看一本书叫《java线程》,网上有英文版的,《操作系统》那么课也会讲到的
进程和线程最大的区别是线程之间可以共享资源,如java中的堆和方法区。多个进程之间则不能共享这些资源

#4


单核CPU里,多线程不能提高程序的效率,但是可以改善用户体验。
有N个核的CPU,最多使用N个线程可以提高效率,在于N个线程只会降低程序的效率。
但是与多线程牺牲的效率相比,用户体验更重要。

#5


引用 2 楼 ticmy 的回复:
就好比你要煮饭和扫地两件事情

你是一直等到饭煮熟才扫地呢还是等待饭煮熟的时间去扫地呢,显然后者效率高

cpu也一样,没有密集型的计算,大部分时间cpu都是处于等待中,多线程就可以利用这些空闲的资源

不一样,CPU不是同时做几件事,CPU中是按任务顺序执行的,单核CPU同时只能做一件事。

#6


并行跟并发的关系

但是这个比喻本身没问题,这个比喻中,人是cpu,煮饭可能是某个阻塞型的IO操作


引用 5 楼 inhibitory 的回复:
引用 2 楼 ticmy 的回复:

就好比你要煮饭和扫地两件事情

你是一直等到饭煮熟才扫地呢还是等待饭煮熟的时间去扫地呢,显然后者效率高

cpu也一样,没有密集型的计算,大部分时间cpu都是处于等待中,多线程就可以利用这些空闲的资源

不一样,CPU不是同时做几件事,CPU中是按任务顺序执行的,单核CPU同时只能做一件事。

#7


引用 5 楼 inhibitory 的回复:
引用 2 楼 ticmy 的回复:

就好比你要煮饭和扫地两件事情

你是一直等到饭煮熟才扫地呢还是等待饭煮熟的时间去扫地呢,显然后者效率高

cpu也一样,没有密集型的计算,大部分时间cpu都是处于等待中,多线程就可以利用这些空闲的资源

不一样,CPU不是同时做几件事,CPU中是按任务顺序执行的,单核CPU同时只能做一件事。


单核CPU可以同时做多件事,只不过他是先执行一件事情的一点点,然后停下,再去执行下一件事情的一点点、
是这样循环执行的、因为CPU的速度非常快,我们是感觉不出来的

#8


引用 6 楼 ticmy 的回复:
并行跟并发的关系

但是这个比喻本身没问题,这个比喻中,人是cpu,煮饭可能是某个阻塞型的IO操作


引用 5 楼 inhibitory 的回复:

引用 2 楼 ticmy 的回复:

就好比你要煮饭和扫地两件事情

你是一直等到饭煮熟才扫地呢还是等待饭煮熟的时间去扫地呢,显然后者效率高

cpu也一样,没有密集型的计算,大部分时间cpu都是处于等待中,多线程就可以……

嘿嘿,忘了IO

#9


谢谢楼上的回复,但是有时多线程可以比单线程的效率高达10倍甚至100倍以上,但是计算机在一个时间片里

只能进行一种操作,虽说运用了多线程,但是任务的总的时间片没有减少啊,那么他们是怎么进行处理的呢,

才可以产生10倍甚至100倍的高效率的呢,所以说计算机在一个时间片只能进行一种操作,而且任务总的时间

片没有减少,那么他们是怎么实现高效率的呢。呵呵,有点钻死牛角了,希望哪位帮我解释一下。

可能我关于线程和进程的关系的理解有些错误,谢谢楼上的指证。

#10


"但是有时多线程可以比单线程的效率高达10倍甚至100倍以上"
@: 这是哪个害人精的理论?

#11


呵呵,我知道多线程的原理是利用cpu在进行IO操作的空闲时间来进行操作,提高了cpu的利用效率,但是整个

任务的时间片总数并没有减少啊,单核的多线程提高的效率没有双核的效率高,双核使一个计算机可以在一个

时间片进行两件事情,但是多线程在单核情况下应该也是可以提高效率的啊,这个不是单双核的原因吧,它是

基于一种什么运行机制呢?哪位高手帮忙解答,在这谢过了。

#12


"但是有时多线程可以比单线程的效率高达10倍甚至100倍以上"
@: 这是哪个害人精的理论? 
 


呵呵,在某些特殊情况下这个比例是可以实现的。

#13


很多时间片是浪费的,所以你经常看到CPU使用率10%以下哦

要是cpu利用率一直是100%,多线程也未必能提高多少效率了

引用 9 楼 genglukuan 的回复:
谢谢楼上的回复,但是有时多线程可以比单线程的效率高达10倍甚至100倍以上,但是计算机在一个时间片里

只能进行一种操作,虽说运用了多线程,但是任务的总的时间片没有减少啊,那么他们是怎么进行处理的呢,

才可以产生10倍甚至100倍的高效率的呢,所以说计算机在一个时间片只能进行一种操作,而且任务总的时间

片没有减少,那么他们是怎么实现高效率的呢。呵呵,有点钻死牛角了,希望哪位帮我解……

#14


呵呵, 就像单进程和多进程一样,他们的更替总是有一定的趋势必然性,多线程是凭借什么优势站住脚的呢?

#15


前面我已经说过线程和进程最大的不同了,就是共享资源的问题

引用 14 楼 genglukuan 的回复:
呵呵, 就像单进程和多进程一样,他们的更替总是有一定的趋势必然性,多线程是凭借什么优势站住脚的呢?

#16


呵呵,这位大哥,我可能没有表达清楚,我问的是多线程相对单线程有什么优势?

#17


1.3 Why Threads?
The notion of threading is so ingrained in Java that it's almost impossible to write even the simplest programs in Java without creating and using threads. And many of the classes in the Java API are already threaded, so often you are using multiple threads without realizing it.

Historically, threading was first exploited to make certain programs easier to write: if a program can be split into separate tasks, it's often easier to program the algorithm as separate tasks or threads. Programs that fall into this category are typically specialized and deal with multiple independent tasks. The relative rareness of these types of programs makes threading in this category a specialized skill. Often, these programs were written as separate processes using operating system-dependent communication tools such as signals and shared memory spaces to communicate between processes. This approach increased system complexity.

The popularity of threading increased when graphical interfaces became the standard for desktop computers because the threading system allowed the user to perceive better program performance. The introduction of threads into these platforms didn't make the programs any faster, but it created an illusion of faster performance for the user, who now had a dedicated thread to service input or display output.

In the 1990s, threaded programs began to exploit the growing number of computers with multiple processors. Programs that require a lot of CPU processing are natural candidates for this category since a calculation that requires one hour on a single-processor machine could (at least theoretically) run in half an hour on a two-processor machine or 15 minutes on a four-processor machine. All that is required is that the program be written to use multiple threads to perform the calculation.

Although computers with multiple processors have been around for a long time, we're now seeing these machines become cheap enough to be very widely available. The advent of less expensive machines with multiple processors, and of operating systems that provide programmers with thread libraries to exploit those processors, has made threaded programming a hot topic as developers move to extract every benefit from these machines. Until Java, much of the interest in threading centered on using threads to take advantage of multiple processors on a single machine.

However, threading in Java often has nothing at all to do with multiprocessor machines and their capabilities; in fact, the first Java virtual machines were unable to take advantage of multiple processors on a machine. Modern Java virtual machines no longer suffer from this limitation, and a multithreaded Java program takes advantage of all the CPUs available on its host machine. However, even if your Java program is destined to be run on a machine with a single CPU, threading is still very important.

One reason that threading is important in Java is that, until JDK 1.4, Java had no concept of asynchronous behavior for I/O. This meant that many of the programming techniques you've become accustomed to using in typical programs were not applicable in Java; instead, until recently, Java programmers had to use threading techniques to handle asynchronous behavior. Another reason is the graphical nature of Java; since the beginning, Java was intended to be used in browsers, and it is used widely in environments with graphical user interfaces. Programmers need to understand threads merely to be able to use the asynchronous nature of the GUI library.

This is not to say there aren't other times when threads are a handy programming technique in Java; certainly it's easy to use Java for a program that implements an algorithm that naturally lends itself to threading. And many Java programs implement multiple independent behaviors. The next few sections cover some of the circumstances in which Java threads are a needed component of the program — either directly using threads or using Java libraries that make heavy use of threads. Many of these circumstances are due to the need for asynchronous behavior or the elegance that threading lends to the program.

 

#18


1.3.1 Nonblocking I/O
In Java, as in most programming languages, when you try to get input from the user, you execute a read() method specifying the user's terminal (System.in in Java). When the program executes the read() method, the program typically waits until the user types at least one character before it continues and executes the next statement. This type of I/O is called blocking I/O : the program blocks until some data is available to satisfy the read() method.

This type of behavior is often undesirable. If you're reading data from a network socket, that data is often not available when you want to read it: the data may have been delayed in transit over the network, or you may be reading from a network server that sends data only periodically. If the program blocks when it tries to read from the socket, it's unable to do anything else until the data is actually available. If the program has a user interface that contains a button and the user presses the button while the program is executing the read() method, nothing happens: the program is unable to handle the mouse events and execute the event processing method associated with the button. This can be very frustrating for the user, who thinks the program has hung.

Traditionally, three techniques are available to handle this situation:




I/O Multiplexing

Developers often take all input sources and use a system call like select() to notify them when data is available from a particular source. This allows input to be handled much like an event from the user (in fact, many graphical toolkits use this method transparently to the developer, who simply registers a callback function that is called whenever data is available from a particular source).

Beginning with JDK 1.4, this feature is provided with the NIO library—a library that allows a programmer to deal with I/O in an asynchronous manner.




Polling

Polling allows a developer to test if data is available from a particular source. If data is available, the data can be read and processed: if it is not, the program can perform another task. Polling can be done either explicitly—with a system call like poll()—or, in some systems, by making the read( ) function return an indication that no data is immediately available.

Polling is also supported by the NIO library of JDK 1.4. In the traditional I/O library, there is only limited support for polling via the available() method of the FilterInputStream class. Unfortunately, this method does not have the rich semantics that polling typically has in most operating systems and is not recommended as a reliable technique to determine whether data is actually available.




Signals

A file descriptor representing the input source can often be set so that an asynchronous signal is delivered to the program when data is available on that input source. This signal interrupts the program, which processes the data and then returns to whatever task it had been doing. Java does not support this technique.

While the issue of blocking I/O can conceivably occur with any data source, it occurs most frequently with network sockets. If you're used to programming sockets, you've probably used one of these techniques to read from a socket, but perhaps not to write to one. Many developers, used to programming on a local area network (LAN), are vaguely aware that writing to a socket may also block, but it's a possibility that many of them ignore because it happens only under certain circumstances, such as a backlog in getting data onto the network. This backlog rarely happens on a fast LAN, but if you're using Java to program sockets over the Internet, the chances of this backlog happening are greatly increased, thus increasing the chance of blocking while attempting to write data onto the network. In Java, you may need two threads to handle the socket: one to read from the socket and one to write to it.

As a result, writing a program that uses I/O means either using multiple threads to handle traditional (blocking) I/O or using the NIO library (or both). The NIO library itself is very complex—much more complex than the thread library. Consequently, it is still often easier to set up a separate thread to read the data (using traditional I/O) from a blocking data source. This separate thread can block when data isn't available, and the other thread(s) in the Java program can process events from the user or perform other tasks.

On the other hand, there are many times when the added complexity of the NIO library is worthwhile and where the proliferation of threads required to process thousands of data sources would be untenable. But using the NIO library doesn't remove all threading complexities; that library has its own thread-related issues.

We examine the threading issues related to I/O in depth in Chapter 12.

#19


1.3.2 Alarms and Timers
Traditional operating systems typically provide some sort of timer or alarm call: the program sets the timer and continues processing. When the timer expires, the program receives some sort of asynchronous signal that notifies the program of the timer's expiration.

In early versions of Java, the programmer had to set up a separate thread to simulate a timer. That thread slept for the duration of a specified time interval and then notified other threads when the timer expired. As Java matured, multiple new classes that provide this functionality were added. These new classes use the exact same technique to provide the functionality, but they hide (at least some of) the threading details from the developer. For complete details on these timers, see Chapter 11.

#20


该回复于2011-01-10 11:30:59被版主删除

#21


那你买本书吧
http://item.taobao.com/item.htm?id=8589723859

第一章第三节

#22


不是,大哥,我一个问题不会我买本书,另一个问题不会我还买本书,几年以后我成开书店的了,大哥,帮帮

忙,大概解释一下是什么意思就行,在这谢过了。

#23


就算是单核CPU
排除进程优先级的话 开启多线程的话 也可以使进程获得更多的时间片 只是计算机整体的计算能力没有提高

#24


大概的意思就是:
多线程可以共享同一个java虚拟机实例中堆和方法区的信息
在有阻塞操作的时候(如blocking IO),可以改善用户体验,比如酷狗,你可以一边下载,一边修改其他歌曲的信息,如果是单线程的,在下载没完成的时候,界面就死在那,直到下载完成

#25


不过,如果做开发,这本书还是值得一看的

#26


大哥,谢谢你,我明天就结贴,今天再挂一天,看看大家还有什么高见。明天准时给分。

#27


引用 2 楼 ticmy 的回复:
就好比你要煮饭和扫地两件事情

你是一直等到饭煮熟才扫地呢还是等待饭煮熟的时间去扫地呢,显然后者效率高

cpu也一样,没有密集型的计算,大部分时间cpu都是处于等待中,多线程就可以利用这些空闲的资源

这个比喻很恰当,多线程用于阻塞并发,也就是有时间休息等待就可以用这个时间干别的事。

#28


目的就是尽量不让可用资源闲着

[img=http://c.rednet.cn/zt/edu/2010nhbaby/api/?vote&3904][/img]

#29


比如以个远程的请求,需要等待请求后的回复,如果请求的响应时间有点久,那么如果是单线程就卡住了,
多线程就继续做其他事情。

#30


LZ不要迷信多线程,单核CPU跑满时,开多少个线程都无法提高效率,还会因线程切换的原因,使效率下降。有阻塞机制的情况下,多线程比较有意义。

#31


使用多线程的一个原因是提高CPU利用率,另一个原因是可以更逼近的描述现实中的并发操作,有时候是有这种需求的。

#32


看看线程池啥的