我正在尝试编写一个Utility类,它有助于在独立线程上执行任务,提供在任务开始前和任务结束后执行任务的能力。
类似于android的AsyncTask
这是这样一节课。
class MySync
{
public void preExecute() {}
public void executeInBackground() {}
public void postExecute() {}
public final void execute()
{
threadExecute.start();
}
private final Thread threadExecute = new Thread()
{
@Override
public void run()
{
try
{
MySync.this.preExecute();
MySync.this.executeInBackground();
MySync.this.postExecute();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
};
}
以下是应该如何使用这个类。类的使用者将根据要求重写这些方法。
class RegisterStudent extends MySync
{
@Override
public void preExecute()
{
System.out.println("Validating Student details. Please wait...");
try
{
Thread.sleep(2000);
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
@Override
public void executeInBackground()
{
System.out.println("Storing student details into Database on Server. Please wait...");
try
{
Thread.sleep(4000);
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
@Override
public void postExecute()
{
System.out.println("Student details saved Successfully.");
}
}
最后开始任务:
public class AsyncDemo
{
public static void main(String... args)
{
new RegisterStudent().execute();
}
}
它似乎运行良好。我的问题是,这是实现标题中提到的目标的正确方式吗?关于如何最好地实现这一点,有什么建议吗?
我不喜欢你的方法,因为你每次创建MySync
的新实例时都会创建一个新线程,如果你打算创建大量的Object实例,这是不可扩展的。此外,创建线程的成本很高,如果我是你,我会使用执行器来限制分配给异步执行任务的线程总数,如果你只想使用一个线程,下面是你可以做的:
ExecutorService executor = Executors.newFixedThreadPool(1);
我也会为类似的东西重新编写你的代码:
public abstract class MySync implements Runnable {
@Override
public final void run() {
try {
preExecute();
executeInBackground();
} finally {
postExecute();
}
}
protected abstract void preExecute();
protected abstract void executeInBackground();
protected abstract void postExecute();
}
通过这种方式,您可以定义所有实现的整个逻辑。
然后你可以这样提交你的任务:
executor.submit(new RegisterStudent());
这不好的地方在于,你强迫用户扩展你的类。在java中,您只能扩展一个类。因此,一个框架不应该剥夺这一点。
而是使用一个接口:
public interface AsyncTask {
public default void preExecute() {}
public default void executeInBackground() {}
public default void postExecute() {}
}
让用户将其传递给您的实用程序类:
class MySync
{
private AsyncTask task;
public MySync(AsyncTask task) {
this.task = task;
}
public final void execute()
{
threadExecute.start();
}
private final Thread threadExecute = new Thread()
{
@Override
public void run()
{
try
{
MySync.this.task.preExecute();
MySync.this.task.executeInBackground();
MySync.this.task.postExecute();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
};
}
Loader正是您想要的。以下是装载机的介绍
https://developer.android.com/guide/components/loaders.html
https://developer.android.com/reference/android/content/Loader.html