2014-10-28 57 views
1

我想设计一个系统,它将以恒定的速率生成一个特定的事件,并且这将继续在后台执行。在前景中,如果需要,还可以输出其他一些事件。 但是后台事件不会停止。在java中实现它的最好方法是什么?Java事件生成

+0

http://en.wikipedia.org/wiki/Observer_pattern – 2014-10-28 19:48:00

+1

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html#newScheduledThreadPool%28int%29 – 2014-10-28 19:48:32

+1

你的意思是像一个计时器? – picciano 2014-10-28 20:19:19

回答

2

这是线程的定义,它需要有一定程度的理解。

在最简单的级别上,创建一个睡眠一段时间的线程然后执行您的代码。还有很多其他的方法可以做到这一点,但很少有人比重写一个线程的运行方法更短。

如果您想要更抽象的东西,请查看Java文档中的并发包,有许多方法可以完全按照您的需要进行,java.util.timer也是一个很好的方法。

请注意不同线程可能同时访问的变量和集合。另外请注意,如果你有一个GUI,你不会从这个新线程更新你的GUI。

编辑添加非线程解决方案

(我不认为这真的是你想要的,但在评论你问一个非螺纹解决方案)。

如果您希望在没有线程的情况下执行此操作(意思是说您确实希望在当前线程中执行此操作),则必须偶尔“中断”当前线程以检查其他任务是否需要处理。首先,你需要这样的方法:

long lastRun=System.currentTimeInMillis(); 
final long howOftenToRun=60*1000 // every minute 

testForBackgroundTask() { 
    if(lastRun + howOftenToRun < System.currentTimeInMillis()) { 
     // This will drift, if you don't want drift use lastRun+=howOftenToRun 
     lastRun=System.currentTimeInMillis() 
     // this is where your occasional task is. 
     // The task could be in-line here but of course that would violate the SRP    
     runBackgroundTask()   
    } 
} 

之后,你需要撒testForBackgroundTask整个代码:

lotsOfStuff.... 
testForBackgroundTask() 
longMethod() 
testForBackgroundTask() 
morestuff... 
testForBackgroundTask() 
... 

注意,如果longMethod()需要很长的时间,那么你就需要把调用放到它里面的testForBackgroundTask()中。

我知道这很难看,而这个解决方案的丑陋之处在于为什么要使用线程。唯一的好处是它绝对可以防止线程冲突。

其他单线程解决方案 - 使您的代码事件驱动 - 更加困难并严重影响您的代码(有一种称为为此目的而设计的有限状态引擎)。

+0

可以在不使用线程的情况下完成吗? – 2014-10-29 09:22:35

+0

正如我所说,你想要的是线程的定义,但你可以做到没有线程,但它带来了自己的一套问题 - 基本上你让你的整个程序事件驱动,然后你的任务只是另一个事件,这是更难比线程(多),但更安全,因为没有并发问题 – 2014-10-29 16:14:57

+1

看看Java.util.timer - 这是一个新的线程,但应该是最简单的实现。 http://www.tutorialspoint.com/java/util/java_util_timer.htm – 2014-10-29 16:17:05