Java如何在作业完成后调用或通知调用类?
我有简单的调用线程哪些做简单的工作。当条件满足时
我想调用或通知基类(启动线程的那个)
工作完成。
这样做的最好方法是什么?Java如何在作业完成后调用或通知调用类?
class TaskThread implements Runnable
{
private int result = -1;
public TaskThread()
{
}
//must be thread safe
public synchronized int getResult()
{
return result;
}
@Override
public void run() {
if(result==-1 || result < 0)
{
StartFoo();
result = InvokeAPI();
if(result == 1)
{
// HERE i like to do something to notify the outside world that the job is done ...
}
}
}
}
//Base class
public class ScheduledThreadsManager {
private static ScheduledThreadsManager instance = null;
private ScheduledExecutorService scheduler;
private Runnable pTaskThread = null ;
protected ScheduledThreadsManager()
{
}
//must be set only once in the app life cycle
public void Init(int corePoolSize,
long TimeUnitINSeconds)
{
pTaskThread = new TaskThread();
scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(pTaskThread,1,TimeUnitINSeconds,TimeUnit.SECONDS);
}
public int getResult()
{
return pTaskThread.;
}
// Runtime initialization
// By defualt ThreadSafe
public static ScheduledThreadsManager getInstance() {
if(instance == null){
synchronized (ScheduledThreadsManager.class) {
if(instance == null){
instance = new ScheduledThreadsManager();
}
}
}
return instance;
}
public void ShutdownNow()
{
pTaskThread = null ;
scheduler.shutdown();
}
}
现在这就是我称之为:
//somewhere in the code
ScheduledThreadsManager.getInstance().init(1,10);
int runThis = true;
while(runThis)
{
int ifOne = ScheduledThreadsManager.getInstance().getResult()
if(ifOne==1)
{
runThis = false;
ScheduledThreadsManager.getInstance().ShutdownNow()
}
}
林不知道,是最好的方法,我可以以某种方式可以从TaskThread run方法方法和更新ScheduledThreadsManager?
您可以通过界面实现它,例如,
interface SomethingToBeCalled{
void notfiy();
}
你BaseClass的扩展了这个
ScheduledThreadsManager implements SomethingToBeCalled{
void notify() {...};
}
,为你的任务建构这个接口
public TaskThread(SomethingToBeCalled smth)
{
this.smth = smth;
}
,现在您可以通知BaseClass的
if(result == 1)
{
smth.notify();
}
我认为最好的办法是给任务的回调函数:
Runnable callback =() -> System.out.println("done!");
然后在你的任务只是在末尾添加callback.run();
。或者,如果您的任务返回了需要使用的值,请使用Consumer
而不是Runnable
。
这里是一个工作示例:
public class Task implements Runnable {
private final Consumer<String> callback;
public Task(Consumer<String> callback) {
this.callback = callback;
}
@Override
public void run() {
// do actual work here instead
String result = new Random().nextInt(2) == 0 ? "a" : "b";
// call a private method in Caller
callback.accept(result);
}
}
public class Caller {
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.submit(new Task((result) -> print(1, result)));
executorService.submit(new Task((result) -> print(2, result)));
executorService.submit(new Task((result) -> print(3, result)));
Thread.sleep(2000);
}
private static void print(int id, String result) {
System.out.println("task " + id + " done, returned: " + result);
}
}
这可以让你如请拨打Caller
的专用方法,您的Task
将不知情。
不要通知调用对象:使用ExecutorService
和Future
。
您可以提交一个Runnable
到ExecutorService
并取回一个Future
:
Future<?> future = executorService.submit(myRunnable);
现在你可以调用future.get()
(任选一超时),这将阻塞,直到未来完成:
future.get();
future.get(5, TimeUnit.MINUTES);
这意味着你不需要引入任何新的回调接口或类似的东西。您也不需要立即致电future.get()
:您可以提交一大堆任务,稍后再致电get
。
请注意,如果您向ExecutorService
提交Callable<T>
,则会返回Future<T>
:如果您希望长时间运行的计算返回值,这非常有用。
番石榴扩展Future
接口与ListenableFuture
,它允许您执行Future
完成后回调。 Java 8也增加了CompleteableFuture
,但我仍然处于黑暗时代,所以我从来没有用过:) :)
这很好,但OP可能不想阻止。如果他阻止,根本没有理由使用'ExecutorService'(假设没有并行性)。 –
@JaroslawPawlak见编辑。 –
除了Guava的'ListenableFuture',你可以使用Java 8的'CompletableFuture'。 – Jesper
http://www.javaworld.com/article/2077462/learn-java/java-tip- 10 - 执行回调 - 例程in-java.html首先命中“Java回调”:D – Fildor
但是,你正在严重overcoding这一点。你可以用Executor和Futures做所有你想要的。参见'submit'。请注意,执行程序的关闭只能确保不能添加新的任务。 – Fildor