Floodlight 入門 之 起步篇 - 如何使用ThreadPool
2017-3-12
今天在寫程序的時候需要用到多線程,查閱Floodlight的官方文檔發現其中有ThreadPool這樣一個Controller模塊…瞬間不敢隨便用ThreadPoolExecutor了,還是先學習一下吧。
官方對該模塊的說明非常簡單:
ThreadPool is a Floodlight module wrapper for a Java’s ScheduledExecutorService. It can be used to have threads be run at specific times or periodically.(ThreadPool這個Floodlight模塊是Java的ScheduledExecutorService的一個封裝。它可以讓線程週期性或按照特定的時序運行。)
這個模塊由IThreadPoolService提供,且不依賴於其他服務。ScheduledExecutorService使用的例子如下:
import static java.util.concurrent.TimeUnit.*;
class BeeperControl {
private final ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1);
public void beepForAnHour() {
final Runnable beeper = new Runnable() {
public void run() { System.out.println("beep"); }
};
final ScheduledFuture<?> beeperHandle =
scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
scheduler.schedule(new Runnable() {
public void run() { beeperHandle.cancel(true); }
}, 60 * 60, SECONDS);
}
}
然而,我看不出來這個跟IThreadPoolService和ThreadPool有什麼關係啊(沒有用到IThreadPoolService和ThreadPool…),於是我又查了官方的Java Doc:
下面是依賴關係:
Class ThreadPool
java.lang.Object
net.floodlightcontroller.threadpool.ThreadPool
All Implemented Interfaces:
IFloodlightModule, IFloodlightService, IThreadPoolService
public class ThreadPool
extends java.lang.Object
implements IThreadPoolService, IFloodlightModule
然後它的成員包括:
域
protected java.util.concurrent.ScheduledExecutorService executor
構造函數
ThreadPool()
方法
方法名 | 原型 | 詳細 |
---|---|---|
getModuleDependencies | java.util.Collection> getModuleDependencies() | 獲取模塊依賴項 |
getModuleServices | java.util.Collection> getModuleServices() | 返回模塊實現的接口 |
getScheduledExecutor | java.util.concurrent.ScheduledExecutorService getScheduledExecutor() | Get the master scheduled thread pool executor maintained by the ThreadPool provider. |
getServiceImpls | java.util.Map,IFloodlightService> getServiceImpls() | Instantiate (as needed) and return objects that implement each of the services exported by this module. |
init | void init(FloodlightModuleContext context) | This is a hook for each module to do its internal initialization, e.g., call setService(context.getService(“Service”)) All module dependencies are resolved when this is called, but not every module is initialized. |
startUp | void startUp(FloodlightModuleContext context) | This is a hook for each module to do its external initializations, e.g., register for callbacks or query for state in other modules It is expected that this function will not block and that modules that want non-event driven CPU will spawn their own threads. |
- 繼承的方法:clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
我們再來看看IThreadPoolService接口:
照舊,我們先看看依賴關係:
All Superinterfaces:
IFloodlightService
All Known Implementing Classes:
ThreadPool
public interface IThreadPoolService
extends IFloodlightService
然後,我們來看看它的方法
方法名 | 原型 | 詳細 |
---|---|---|
getScheduledExecutor | java.util.concurrent.ScheduledExecutorService getScheduledExecutor() | Get the master scheduled thread pool executor maintained by the ThreadPool provider. |
好的,現在我們知道了,這裏的ThreadPool只是對ScheduledExecutorService進行了封裝,最後使用的還是ScheduledExecutorService對象。所以現在讓我們來看看ScheduledExecutorService是什麼樣的:
ScheduledExecutorService的依賴關係:
All Superinterfaces:
Executor, ExecutorService
All Known Implementing Classes:
ScheduledThreadPoolExecutor
public interface ScheduledExecutorService
extends ExecutorService
ScheduledExecutorService的方法:
方法名 | 原型 | 詳細 |
---|---|---|
schedule | ScheduledFuture schedule(Callable callable, long delay, TimeUnit unit) | |
schedule | ScheduledFuture schedule(Runnable command, long delay, TimeUnit unit) | |
scheduleAtFixedRate | ScheduledFuture scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) | |
scheduleWithFixedDelay | ScheduledFuture scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) |
ScheduledExecutorService繼承的方法:
awaitTermination, invokeAll, invokeAll, invokeAny, invokeAny, isShutdown, isTerminated, shutdown, shutdownNow, submit, submit, submit(Methods inherited from interface java.util.concurrent.ExecutorService)
execute(Methods inherited from interface java.util.concurrent.Executor)
官方給出的文檔中主要說明也就這些了,我們現在結合Floodlight的代碼來看一下,我們該如何使用這些模塊和API:
這邊舉的例子還用到了Floodlight的另一個類SingletonTask,它可以讓創建的線程只跑一次,我們來看看官方文檔的說明吧(不要急):
依賴關係:
Class SingletonTask
java.lang.Object
net.floodlightcontroller.core.util.SingletonTask
public class SingletonTask
extends java.lang.Object
官方文檔在開頭balbala說了一大段爲什麼要有這個類,然後指出了這個類的一個特點:當創建的任務還沒有開始時,你是沒有辦法創建一個新的任務的;當創建的任務運行時,它會設置一個標誌位,當任務運行結束時它會重新再運行一次。
因爲我們重點不在SingletonTask,所以這裏僅僅簡單介紹一下我們要用的方法。首先我們要看的是它的構造函數:
SingletonTask(java.util.concurrent.ScheduledExecutorService ses, java.lang.Runnable task)
我們可以看到,構造函數的第一個參數是java.util.concurrent.ScheduledExecutorService,這個我們可以通過IThreadPoolService的getScheduledExecutor方法獲得。然後第二個參數是java.lang.Runnable,這個就可以放實現了Runnable接口的對象了。
構造函數搞定後,肯定還是要調用它的一些方法來控制任務的運行的。所以我們接下來看看它的方法。它的方法很簡單,只有一個:
void reschedule(long delay, java.util.concurrent.TimeUnit unit)
官方文檔中對該方法的說明如下:當目前已經沒有任務被調度則讓當前的任務運行。如果已經有一個任務被調度了,但還沒有開始,它就會取消這個任務並在給定的時間內重新調度這個任務,讓它運行。如果一個任務已經開始了…這句話寫的有點看不太懂( If the task is already started, it will cause the task to be rescheduled once it completes to run after delay from the time of reschedule.)我這邊的翻譯是如果該任務在reschedule給定的時間延遲後完成了運行,則它將會讓這個任務重新被調度。而我的理解是,如果在給定時間內,當前運行的任務沒有結束,它就會重新運行新的任務。
我們看看reschedule的參數,這很簡單,第一個參數是延時時間的數值,第二個參數是單位。
到此爲止,我們就可以完成一個簡單的例子了:
class worker implement Runnable
{
public worker()
{
}
void run()
{
System.out.println("working");
}
}
SingletonTask task = new SingletonTask(IThreadPoolService.getScheduledExecutor(),new worker());
task.reschedule(500,TimeUnit.MILLISECONDS);