当前位置:天才代写 > tutorial > JAVA 教程 > 在Java中如何实现长时间任务

在Java中如何实现长时间任务

2017-11-12 08:00 星期日 所属: JAVA 教程 浏览:270

摘要: 在软件开拓中,我们常常面对着处理惩罚长时间任务的多线程编程问题。在我们的ezOne平台的开拓中就多处涉及到,如JPC数据处事JPC数据处理惩罚处事 报警联动 门禁系统等。本人在编写DEMO措施的进程中几易其稿,煞操心机,但依然感受有很多处所需要改造,为了淘汰多线程编程带来的风险,我翻译整理了一个雷同问题的办理方案框架以到达一劳永逸。 为了便于阅读,保存原文。引用请保存作者和文章来历。

要害词: Thread、 Lock 、 Notification、长时间任务。

在应用措施中我们常常需要一个类去完成像数据处理惩罚、监听事件或查抄另一个类的勾当等任务。为了到达这个方针,我们大概利用带有一套锁和动静通知的线程。JAVA 线程API已经很好的文档化,但为了使线程可以或许正确而高效地运行,措施员仍然需要富厚的编程履历并编写大量的代码。通过应用本篇文章中接头的框架,措施员可以或许制止忍受煎熬写大量的代码,快速建设结实的应用措施。 二、长时间运行任务的措施框架。

关于长时间运行的任务的主要工作是如安在应用措施的生命期使它一直保持运行。实现的得当要领是提供一个线程来执行这个特定的任务。我们可以通过担任Thread类或实现java.lang.Runnable接口来到达该方针。假如回收实现Runnable接口的方法,就可以可以或许得到更好的面向工具的设计,同时可以制止JAVA中的单担任问题。别的,我们也能更有效的处理惩罚Runnable实例(譬喻利用线程池凡是需要一个Runnable实例而不是线程来运行)。

框架的基本是一个叫Worker的抽象类,它实现了Runnable接口,并提供了有效处理惩罚任务的好要领。这些要领有些已经被实现,如run()要领,但有些是抽象要领,开拓人员必需本身来实现。假如要建设一个长时间运行的类,你只需要担任Worker类并实现几个抽象要领。让我们看看这些要领的细节。

Worker 类的run()要领被设计成只要不断止运行就一连的执行work()要领。work()要领可以认真数据处理惩罚、事件响应、文件读写、,执行SQL呼吁等操纵。这样work()要领可以或许抛出异常,并将异常传给run(),然后由run()要领来处理惩罚这些异常。

run()要领有表里两层try-catch语句:一层处于while-loop轮回外,一层在while-loop轮回内。前一个try-catch用于捕捉非编程异常以确保run()要领不退出。后一个try-catch语句捕捉关于业务逻辑和相应行为的各类异常。假如在work()要领中产生了一些期待操纵(譬喻期待一个输入流或一个Socket),抛出一个InterruptedException的要领是可取的。要记着的是只要应用措施在运行,work()要领不需要任何while-loop轮回去维持它运行,这一切由Worker代劳了。

run()开始时,挪用prepareWorker()要领来筹备长时间运行任务需要的所有资源(参考措施清单A)。譬喻 ,在这个要领中可以打开一个将要用到的数据库毗连或文件。尤其对付那些像成立一个socket这样的阻塞操纵放在这儿是很好的。因为若让它们在一个独立的线程中运行,则不会阻塞主线程的执行。

与前面要领相反的是releaseWorker(),它在run()要领筹备退出时被挪用(参考措施清单A)。在该要领中你可以编写那些释放系统资源或执行其它排除行动的代码。该要领雷同于java.lang.Object.finalize(),但它在线程中止时被显式的挪用。

三、框架中的错误处理惩罚机制

另一个重要的要领是handleError(),它带有一个java.lang.Throwable的输入参数。在run()要领每次产生错误时挪用这个要领。这依赖于你怎么实现错误处理惩罚。要领之一是写错误日志并通过挪用halt()要领中止任务(参考措施清单A)。

isCondition()要领用于判定work()要领是否可以或许被执行。因此答允细粒度地节制任务。这在事件触发的框架中很是有用。当work()要领的执行条件未满意时,work要领将被挂起,直到条件完全满意(譬喻,缓存区非空)。在Worker的实现中这个条件将按在要领setTimeout()中指定的时间周期地查抄一个锁通知。假如在任务中不需要任何期待阻塞,仅仅只要使isCondition()要领老是返回真值。

四、任务终止机缘

你还需要isRunning(), broadcast(), halt()要领。通过会见isRunning()要领,你将能查抄某个任务是否正在运行,并抉择是否中止它。broadcast()要领正确地通知锁工具,而且假如这个工具一直期待这个锁,那么就激活这个任务。halt()要领中止一个任务,因此下一isRunning()状态一旦被挪用,run()要领就退出,因为这个要领只通知谁人大概阻塞这个任务线程的锁。当在work()要领中执行阻塞功课时用沟通的锁是明智的。假如你不能用沟通的锁工具时,譬喻在执行java.io.InputStream.read()要领碰着阻塞时,你就应该添加所有大概锁的显式通知可能增加java.lang.Thread.interrupt()到halt()中。假如一个你阻塞的工具被正确处理惩罚,java.lang.Thread.interrupt()将会起浸染。譬喻,它在InputStream.read()执行时有浸染,但在执行java.sql.PreparedStatement.execute()不起浸染,因此在每个非凡的条件下你必需测试halt()要领。

#p#分页标题#e#

一旦你熟悉Worker类,你就很容易建设你本身的实现(参考措施清单B),为了把这类看成一个线程运行,仅仅只需简朴地利用 new Thread(new WaitedWorker()).start。应用Thread.interrupt()或Worker.halt()或它们的组合,你就可以精确的节制任务的执行。譬喻当JVM通过在java.lang.Runtime.addShutdownHook()要领中放相应的代码遏制时,你就能遏制所有的任务。

五、结论

我们已经查抄了长时间运行任务框架,而且看到奈何通过从建设一个基于它的抽象类的任务。它的构架是清晰和机动的,而且被设计成可扩展的。用这个框架你能制止为创作类而绞尽脑汁,而且辅佐你可以或许开拓出高效、靠得住的应用措施。

 

    关键字:

天才代写-代写联系方式