2013-01-08 46 views
2

我可以做这样的事情在Java中:方法返回Runnable对象

protected Runnable getRunnable(final int seconds) { 
    Runnable runnable = new Runnable() { 
     public void run() { 
       sendData();    
       try { 
        Thread.sleep(seconds * 1000); 
       } 
       catch (InterruptedException e) { 
        Thread.currentThread().interrupt(); 
       } 
     } 
    }; 
    return runnable; 
} 

然后:

protected void startTimer(int seconds) throws InterruptedException,NullPointerException { 
    Thread thread = new Thread(getRunnable(seconds)); 
    thread.start(); 
} 

是上述过程中的安全?

+3

“上述过程是否安全?” =>从哪个角度来看?代码中没有共享状态或变量,因此它是线程安全的。然而'sendData'方法可能不是... – assylias

+1

你试过了吗? –

+0

你想做什么? – Julien

回答

2

在评论你说

所有我想要做的就是执行的SendData()方法每几秒钟的特定量(即每15秒)

然后用内置定时器,它会为你组织,例如:

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); 
Runnable r = new Runnable() { 
    @Override 
    public void run() { 
     sendData(); 
    } 
}; 
ScheduledFuture<?> future = scheduler.scheduleAtFixedRate(r, 0, 15, TimeUnit.SECONDS); 

//when you want to cancel the scheduled task 
future.cancel(true); 

//and before you leave your program, don't forget to call: 
scheduler.shutdown(); 
+0

好的答案。顺便说一句,如果我想停止前面提到的,我该怎么做?我的意思是说,这将每隔15秒(永远)运行。我怎样才能中断线程? –

+0

@AlexDowining通过取消返回的未来 - 请参阅我的编辑。 – assylias

2

你试过了吗?答案是它确实有效。 Runnable是一个由Object(上例中的匿名类)实现的接口,您可以像其他任何对象一样传递/引用它。

请注意,因为上面是一个内部类,所以对外部(周围)类有一个隐式引用。

+0

由于问题被标记为“线程安全”,我不确定问题是关于是否可以创建实现Runnable的匿名类。但也许这是... – assylias

+0

它似乎工作。不过,我是小白,我害怕线程。从我所拥有的小经验中,我意识到,用你永远不知道的线程! –

3

是的,它是安全的(假设sendData本身是安全的),但我不确定你期望它做什么。你写的代码将创建一个新的线程,将立即调用sendData(),然后在sendData返回后线程将休眠几秒钟,然后终止而不做任何其他事情(所以睡眠是毫无意义的,除了防止JVM退出或Runnable或其包含对象被垃圾收集直到睡眠结束)。如果您希望它在之前等待,请致电sendData,那么您需要交换一些东西。

+0

因为我认为这就是问题所在,所以值得强调的是'sendData'必须是线程安全的。当前的实现很容易允许某人通过'getRunnable'获取'Runnables'的负载,然后立即连续启动它们。如果'sendData'不注意它的作用,所有地狱都会破裂...... – us2012