JAVA网页设计Java多线程编程形式实战指南:Active Object形式(下)仓酷云
主要缺点就是:速度比较慢,没有C和C++快ActiveObject形式的评价与完成考量ActiveObject形式经由过程将办法的挪用与实行分别,完成了异步编程。有益于进步并发性,从而进步体系的吞吐率。
ActiveObject形式另有个优点是它能够将义务(MethodRequest)的提交(挪用异步办法)和义务的实行战略(ExecutionPolicy)分别。义务的实行战略被封装在Scheduler的完成类以内,因而它对外是不“可见”的,一旦必要变化也不会影响别的代码,下降了体系的耦合性。义务的实行战略能够反应以下一些成绩:
[*]接纳甚么按次往实行义务,如FIFO、LIFO、大概基于义务中包括的信息所定的优先级?
[*]几个义务能够并发实行?
[*]几个义务能够被列队守候实行?
[*]假如有义务因为体系过载被回绝,此时哪一个义务该被选中作为就义品,使用程序该怎样被关照到?
[*]义务实行前、实行后必要实行哪些操纵?
这意味着,义务的实行按次能够和义务的提交按次分歧,能够接纳单线程也能够接纳多线程往实行义务等等。
固然,优点的面前老是埋没着价值,ActiveObject形式完成异步编程也有其价值。该形式的介入者有6个之多,实在现历程也包括了很多两头的处置:MethodRequest对象的天生、MethodRequest对象的挪动(收支缓冲区)、MethodRequest对象的运转调剂和线程高低文切换等。这些处置都有其空间和工夫的价值。因而,ActiveObject形式合适于分化一个对照耗时的义务(如触及I/O操纵的义务):将义务的倡议和实行举行分别,以削减不用要的守候工夫。
固然形式的介入者较多,但正如本案牍例的完成代码所展现的,个中年夜部分的介入者我们能够使用JDK本身供应的类来完成,以节俭编码工夫。如表1所示。
表1.利用JDK现有类完成ActiveObject的一些介入者
介入者称号
能够借用的JDK类
备注
Scheduler
JavaExecutorFramework中的java.util.concurrent.ExecutorService接口的相干完成类,如java.util.concurrent.ThreadPoolExecutor。
ExecutorService接口所界说的submit(Callable<T>task)办法相称于中的enqueue办法。
ActivationQueue
java.util.concurrent.LinkedBlockingQueue
若Scheduler接纳java.util.concurrent.ThreadPoolExecutor,则java.util.concurrent.LinkedBlockingQueue实例作为ThreadPoolExecutor机关器的参数。
MethodRequest
java.util.concurrent.Callable接口的匿名完成类。
Callable接口比起Runnable接口的上风在于它界说的call办法有前往值,便于将该前往值传送给Future实例。
Future
java.util.concurrent.Future
ExecutorService接口所界说的submit(Callable<T>task)办法的前往值范例就是java.util.concurrent.Future。
毛病断绝
毛病断绝指一个义务的处置失利不影响别的义务的处置。每一个MethodRequest实例能够看做一个义务。那末,Scheduler的完成类在实行MethodRequest时必要注重毛病断绝。选用JDK中现成的类(如ThreadPoolExecutor)来完成Scheduler的一个优点就是这些类大概已完成了毛病断绝。而假如本人编写代码完成Scheduler,用单个ActiveObject事情线程一一实行一切义务,则必要出格注重线程的run办法的非常处置,确保不会由于一般义务实行时碰到一些运转时非常而招致全部线程停止。如清单6的示例代码所示。
清单6.本人下手完成Scheduler的毛病断绝示例代码
publicclassCustomSchedulerimplementsRunnable{privateLinkedBlockingQueue<Runnable>activationQueue=newLinkedBlockingQueue<Runnable>();@Overridepublicvoidrun(){dispatch();}public<T>Future<T>enqueue(Callable<T>methodRequest){finalFutureTask<T>task=newFutureTask<T>(methodRequest){@Overridepublicvoidrun(){try{super.run();//捕捉以是大概抛出的对象,制止该义务运转失利而招致其地点的线程停止。}catch(Throwablet){this.setException(t);}}};try{activationQueue.put(task);}catch(InterruptedExceptione){Thread.currentThread().interrupt();}returntask;}publicvoiddispatch(){while(true){RunnablemethodRequest;try{methodRequest=activationQueue.take();//避免一般义务实行失利招致线程停止的代码在run办法中methodRequest.run();}catch(InterruptedExceptione){//处置该非常}}}}缓冲区监控
假如ActivationQueue是有界缓冲区,则对缓冲区确当前巨细举行监控不管是关于运维仍是测试来讲都有其意义。从测试的角度来看,监控缓冲区有助于断定缓冲区容量的倡议值(公道值)。清单3所示的代码,便是经由过程准时义务周期性地挪用ThreadPoolExecutor的getQueue办法对缓冲区的巨细举行监控。固然,在监控缓冲区的时分,常常只必要大抵的值,因而在监控代码中要制止不用要的锁。
缓冲区饱和处置战略
当义务的提交速度年夜于义务的实行数率时,缓冲区大概渐渐积存到满。这时候新提交的义务会被回绝。不管是本人编写代码仍是使用JDK现有类来完成Scheduler,关于缓冲区满时新义务提交失利,我们必要一个处置战略用于决意此时哪一个义务会成为“就义品”。若利用ThreadPoolExecutor来完成Scheduler有个优点是它已供应了几个缓冲区饱和处置战略的完成代码,使用代码能够间接挪用。如清单3的代码所示,本案牍例中我们选择了丢弃最老的义务作为处置战略。java.util.concurrent.RejectedExecutionHandler接口是ThreadPoolExecutor对缓冲区饱和处置战略的笼统,JDK中供应的详细完成如表2所示。
表2.JDK供应的缓冲区饱和处置战略完成类
完成类
所完成的处置战略
ThreadPoolExecutor.AbortPolicy
间接抛出非常。
ThreadPoolExecutor.DiscardPolicy
保持以后被回绝的义务(而不抛出任何非常)。
ThreadPoolExecutor.DiscardOldestPolicy
将缓冲区中最老的义务保持,然后从头实验回收被回绝的义务。
ThreadPoolExecutor.CallerRunsPolicy
在义务的提交方线程中运转被回绝的义务。
固然,关于ThreadPoolExecutor而言,其事情行列满纷歧定就意味着新提交的义务会被回绝。当其最年夜线程池巨细年夜于其中心线程池巨细时,事情行列满的情形下,新提交的义务会用一切中心线程以外的新增线程来实行,直到事情线程数到达最年夜线程数时,新提交的义务会被回绝。
Scheduler余暇事情线程清算
假如Scheduler接纳多个事情线程(如接纳ThreadPoolExecutor如许的线程池)来实行义务。则大概必要清算余暇的线程以勤俭资本。清单3的代码就是间接利用了ThreadPoolExecutor的现有功效,在初始化实在例时经由过程指定其机关器的第3、4个参数(longkeepAliveTime,TimeUnitunit),告知ThreadPoolExecutor关于中心事情线程之外的线程若其已余暇了指准时间,则将其清算失落。
可复用的ActiveObject形式完成
只管使用JDK中的现成类能够极年夜地简化ActiveObject形式的完成。但假如必要频仍地在分歧场景下利用ActiveObject形式,则必要一套更利于复用的代码,以勤俭编码的工夫和使代码加倍易于了解。清单7展现一段基于Java静态代办署理的可复用的ActiveObject形式的Proxy介入者的完成代码。
清单7.可复用的ActiveObject形式Proxy介入者完成
importjava.lang.reflect.InvocationHandler;importjava.lang.reflect.InvocationTargetException;importjava.lang.reflect.Method;importjava.lang.reflect.Proxy;importjava.util.concurrent.Callable;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Future;publicabstractclassActiveObjectProxy{privatestaticclassDispatchInvocationHandlerimplementsInvocationHandler{privatefinalObjectdelegate;privatefinalExecutorServicescheduler;publicDispatchInvocationHandler(Objectdelegate,ExecutorServiceexecutorService){this.delegate=delegate;this.scheduler=executorService;}privateStringmakeDelegateMethodName(finalMethodmethod,finalObject[]arg){Stringname=method.getName();name="do"+Character.toUpperCase(name.charAt(0))+name.substring(1);returnname;}@OverridepublicObjectinvoke(finalObjectproxy,finalMethodmethod,finalObject[]args)throwsThrowable{ObjectreturnValue=null;finalObjectdelegate=this.delegate;finalMethoddelegateMethod;//假如拦阻到的被挪用办法是异步办法,则将其转发到响应的doXXX办法if(Future.class.isAssignableFrom(method.getReturnType())){delegateMethod=delegate.getClass().getMethod(makeDelegateMethodName(method,args),method.getParameterTypes());finalExecutorServicescheduler=this.scheduler;Callable<Object>methodRequest=newCallable<Object>(){@OverridepublicObjectcall()throwsException{Objectrv=null;try{rv=delegateMethod.invoke(delegate,args);}catch(IllegalArgumentExceptione){thrownewException(e);}catch(IllegalAccessExceptione){thrownewException(e);}catch(InvocationTargetExceptione){thrownewException(e);}returnrv;}};Future<Object>future=scheduler.submit(methodRequest);returnValue=future;}else{//若拦阻到的办法挪用不是异步办法,则间接转发delegateMethod=delegate.getClass().getMethod(method.getName(),method.getParameterTypes());returnValue=delegateMethod.invoke(delegate,args);}returnreturnValue;}}/***天生一个完成指定接口的ActiveObjectproxy实例。*对interf所界说的异步办法的挪用会被装发到servant的响应doXXX办法。*@paraminterf要完成的ActiveObject接口*@paramservantActiveObject的Servant介入者实例*@paramschedulerActiveObject的Scheduler介入者实例*@returnActiveObject的Proxy介入者实例*/publicstatic<T>TnewInstance(Class<T>interf,Objectservant,ExecutorServicescheduler){@SuppressWarnings("unchecked")Tf=(T)Proxy.newProxyInstance(interf.getClassLoader(),newClass[]{interf},newDispatchInvocationHandler(servant,scheduler));returnf;}}清单7的代码完成了可复用的ActiveObject形式的Proxy介入者ActiveObjectProxy。ActiveObjectProxy经由过程利用Java静态代办署理,静态天生指定接口的代办署理对象。对该代办署理对象的异步办法(即前往值范例为java.util.concurrent.Future的办法)的挪用会被ActiveObjectProxy完成InvocationHandler(DispatchInvocationHandler)所拦阻,并转发给ActiveObjectProxy的newInstance办法中指定的Servant处置。
清单8所示的代码展现了经由过程利用ActiveObjectProxy疾速ActiveObject形式。
清单8.基于可复用的API疾速完成ActiveObject形式
J2ME在手机游戏开发的作用也是无用质疑的。至于桌面程序,可能有人说java不行,界面不好看,但是请看看net网页编程Beans和Eclipse吧,他们都是利用java开发的,而他们的界面是多么的华丽,所以界面决不是java的缺点。还有一个不得不提的优点就是大多java人员都挂在嘴边的java的跨平台性,目前这确实也是java优点之一。 多重继承(以接口取代)等特性,增加了垃圾回收器功能用于回收不再被引用的对象所占据的内存空间,使得程序员不用再为内存管理而担忧。在 Java 1.5 版本中,Java 又引入了泛型编程(Generic Programming)、类型安全的枚举、不定长参数和自动装/拆箱等语言特性。 是一种将安全性(Security)列为第一优先考虑的语言 接着就是EJB了,EJB就是Enterprise JavaBean, 看名字好象它是Javabean,可是它和Javabean还是有区别的。它是一个体系结构,你可以搭建更安全、更稳定的企业应用。它的大量代码已由中间件(也就是我们常听到的 Weblogic,Websphere这些J2EE服务器)完成了,所以我们要做的程序代码量很少,大部分工作都在设计和配置中间件上。 Java 不同于一般的编译执行计算机语言和解释执行计算机语言。它首先将源代码编译成二进制字节码(bytecode),然后依赖各种不同平台上的虚拟机来解释执行字节码。从而实现了“一次编译、到处执行”的跨平台特性。 Java是一种计算机编程语言,拥有跨平台、面向对java 是一种突破用户端机器环境和CPU Sun公司看见Oak在互联网上应用的前景,于是改造了Oak,于1995年5月以Java的名称正式发布。Java伴随着互联网的迅猛发展而发展,逐渐成为重要的网络编程语言。 http://www.jdon.com/去下载,或到同济技术论坛的服务器ftp://nro.shtdu.edu.cn去下,安装上有什么问题,可以到论坛上去提问。
页:
[1]