在我的Android项目中,我有很多地方需要异步运行一些代码(Web请求,对db的调用等)。这不是长时间运行的任务(最多几秒钟)。到目前为止,我一直在通过创建新线程,将任务传递给新的可运行线程来进行此类操作。但是最近我读了一篇有关Java中线程和并发的文章,并且了解到为每个任务创建一个新的Thread并不是一个好的决定。
所以现在我ThreadPoolExecutor
在我的Application
课堂上创建了一个包含5个线程的。这是代码:
public class App extends Application {
private ThreadPoolExecutor mPool;
@Override
public void onCreate() {
super.onCreate();
mPool = (ThreadPoolExecutor)Executors.newFixedThreadPool(5);
}
}
而且我还有一种方法可以将Runnable任务提交给执行者:
public void submitRunnableTask(Runnable task){
if(!mPool.isShutdown() && mPool.getActiveCount() != mPool.getMaximumPoolSize()){
mPool.submit(task);
} else {
new Thread(task).start();
}
}
因此,当我想在代码中运行异步任务时,我得到的实例,App
并调用submitRunnableTask
将可运行对象传递给它的方法。如您所见,我还检查线程池中是否有空闲线程来执行任务,否则,我将创建一个新线程(我不认为会发生这种情况,但是无论如何……我不会希望我的任务排在队列中并降低应用速度)。
在onTerminate
应用程序的回调方法中,我关闭了池。
所以我的问题是:这种模式是否比在代码中创建新线程更好?我的新方法有什么优点和缺点?会导致我尚不了解的问题吗?您能建议我一些比这更好的html" target="_blank">方法来管理我的异步任务吗?
PS:我在Android和Java方面有一定的经验,但是我并不是一名并发专家。)因此,在某些问题上可能有些方面我不太了解。任何建议将被认真考虑。
该答案假设您的任务很短
这样的模式是否比在代码中创建新的线程更好?
更好,但仍远非理想。您 仍在为短期任务创建线程 。相反,您只需要创建其他类型的线程池-例如by
Executors.newScheduledThreadPool(int corePoolSize)
。
行为上有什么区别?
FixedThreadPool
将始终具有一组要使用的线程,并且如果所有线程都忙,则将新任务放入队列。ScheduledThreadPool
由Executors
类创建的(默认)(即使空闲)具有 最小的 线程池。如果有新任务出现时所有线程都忙, 它将为它创建一个新线程 ,并在完成后60秒钟处理该线程,除非再次需要它。第二个可以让您不要自己创建新线程。无需“预定”部分就可以实现此行为,但是您将不得不自己构造执行程序。构造函数是
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue)
各种选项使您可以微调行为。
如果有些任务很长…
我的意思是很长。与您的应用程序生命周期中的大部分时间一样(实时2路连接?服务器端口?多播侦听器?)。在这种情况下,将您Runnable
的遗嘱执行人置于不利地位–标准的遗嘱执行人
并非 旨在应对这种情况,它们的性能将下降。
考虑一下您的固定线程池-如果您有5个长时间运行的任务,那么任何新任务都会产生一个新线程,从而完全破坏该池的所有可能收益。如果您使用更灵活的执行程序-
一些线程将被共享,但并非总是如此。
经验法则是
在我的Android项目中,我有很多地方需要异步运行一些代码(web请求、对db的调用等)。这是运行时间不长的任务(最多几秒钟)。到目前为止,我一直在做这种事情,创建一个新线程,并通过任务传递给它一个新的runnable。但是最近我读了一篇关于Java中的线程和并发性的文章,我明白了为每个任务创建一个新线程并不是一个好的决定。 因此,现在我已经在我的类中创建了一个,它包含5个线程。代码如下: 我还
本文向大家介绍Thread 类中的start() 和 run() 方法有什么区别?相关面试题,主要包含被问及Thread 类中的start() 和 run() 方法有什么区别?时的应答技巧和注意事项,需要的朋友参考一下 start()方法可以用来启动线程,调用该方法,会创建一个新的线程,然后内部执行run()方法;不能多次调用,否则会抛异常 直接调用run()方法,不会创建新的线程;可以进行多次调
问题内容: 假设我们有以下两个Runnable: 那么这有什么区别: 和这个: 问题答案: 第一个示例:没有多个线程。两者都在单个(现有)线程中执行。没有线程创建。 只是实现接口并因此实现run()方法的类的两个不同对象。调用时,你正在当前线程中执行它。 第二个示例:两个单独的线程。 t1并且t2是该类的对象。当你调用时,它将启动一个新线程并在内部调用该run()方法r1以在该新线程中执行该方法。
问题内容: 请解释以下代码的输出: 如果我致电,输出为: 如果我致电,输出为: 为什么会有这种不一致?请解释。 问题答案: 该方法启动一个新线程,该线程的入口点就是方法。如果直接调用run(),它将在同一线程中执行。假设调用将启动一个新的执行线程,则该方法可在其余主方法执行之后(如您的示例)被调用。 将您的main方法更改为调用并重复运行,您会发现有时它会输出: 有时它输出: 取决于Java选择如
问题内容: 好标题说,和之间有什么区别 问题答案: 行为上,几乎没有。 但是,一旦有了一个实例,就可以向它提交多个任务,并使它们一个接一个地执行。您不能仅仅使用raw来做到这一点。
问题内容: 假设我们有以下两个Runnable: 那么这有什么区别: 还有这个: 问题答案: 第一个示例:没有多个线程。两者都在单个(现有)线程中执行。没有线程创建。 和只是实现接口并因此实现方法的类的两个不同对象。调用时,你正在当前线程中执行它。 第二个示例:两个单独的线程。 并且是该类的对象。当你调用时,它将启动一个新线程并在内部调用该方法r1以在该新线程中执行该方法。