JDK 5.0 concurrent学习(一) |
整个的列出顺序是在我学习concurrent javadoc的顺序上,按照依赖关系排序,依赖其他JDK 5.0中类越少、越容易理解的排在越前面。
顾名思义,就是时间的单位。以前如果调用方法需要传入时间参数,时间参数的单位都是通过javadoc说明的,比如说Thread.sleep(long),时间的参数就是毫秒,如果需要休眠一秒,则需要调用Thread.sleep(1000)。 JDK 5.0中加入了该类,为时间数字后面加上了个单位,如TimeUnit.MILLISECONDS是毫秒, TimeUnit.SECONDS是秒,等等。目前感觉上用处并不是太大,如果说原来某调用只需要一个参数,那现在就需要传两个参数,实现类也需要通过传入的两个参数进行转换,反而麻烦了一些。稍微有些为了OO而OO的嫌疑:) 示例: 假设某方法的声明是invoke(int time, TimeUnit timeUnit),那么在理论上invoke(1, TimeUnit.SECONDS)和invoke(1000,TimeUnit.MILLISECONDS)是等价的,当然,如果实现中没有做判断,结果还是会不一样。
单方法接口,非常类似于Runnable,之所以存在该接口而不是用Runnable接口的原因就是:Callable可以有返回值,并可以抛出checked异常。其方法声明为:V call() throws Exception 通过javadoc可以看到,在concurrent包中的不少方法有method(Callable)和method(Runnable,T)这两种形式,如ExecutorService.submit/FutureTask的构造方法等等。但我的感觉是如果存在着不少的这类方法,为什么不通过一个简单的包装类来做Runnable和Callable之间的转换,却采用众多的方法重载来实现?我个人认为如method(new CallableWrapper(Runnable,T))这种形式似乎更好一点。
其表现了一个异步操作的结果,该类是POSA2中的Active Object的一个重要组成部分。 在异步操作中,方法调用和方法执行是分开的,比如可以在时间点1时,A调用了B的一个方法去执行某项操作并立即返回,而该操作实际上在时间点2才执行完毕,那么Future类就可以表现整个异步操作的结果,如A调用B方法时返回的就是一个Future对象,可以通过调用future.isDone()来判断该异步操作是否完成,可以调用future.cancel(boolean)来取消尚未执行或中止正在执行的异步操作,还可以通过future.get()来得到异步操作的结果,如果异步操作尚未完成,该方法会一直阻塞,知道该异步操作完成。 目前我所接触到的异步操作大多是通过IOC来实现的。一般IOC都是在方法调用时或方法调用前注册一个回调钩子,等到方法执行完毕,再通过这个回调钩子通知调用者。就用Cindy中一个简单的例子来说明: session.addSessionListener(new SessionAdapter() { 这种方式对于回调控制的比较弱,什么时候回调,会在哪个线程内被回调,应用无法控制。而Future表现的则是表现异步操作的另一种方式,控制权掌握在调用者本身,如上面的代码用Future来改写: Future future = session.start(); 可以看到,这种方式所有的控制权都在于调用者本身,比如可以做到如果在1s内该操作还未执行完毕,则取消该操作等等。但是IOC的方式并不是没有价值的,它拥有更大的吞吐量,可以看出,如果要得到异步的结果,Future方式要么是采用轮询去判断操作是否完成,要么是采用阻塞等待的方式,不管是采用哪种方式,系统总体的吞吐量都会降低(尽管相对于同步调用,系统的总体吞吐量是上升了)。 我的观点是: 吞吐量角度: 同步调用 < 异步Future方式 < 异步IOC方式 采用何种方式,要依据设计什么样的系统而定,嘿嘿,废话:) |
|
JDK 5.0 concurrent学习(一)
最新推荐文章于 2021-11-02 17:20:49 发布