Java 如何使用ExecutorService修复程序?
所以,我是Java新手 我写了一个相对简单的程序,可以处理很多文件 它很慢,我想运行多个线程。在StackOverflow社区的帮助下,我制作了如下内容:Java 如何使用ExecutorService修复程序?,java,executorservice,Java,Executorservice,所以,我是Java新手 我写了一个相对简单的程序,可以处理很多文件 它很慢,我想运行多个线程。在StackOverflow社区的帮助下,我制作了如下内容: public class FileProcessor { public static void main(String[] args) { // run 5 threads ExecutorService executor = Executors.newFixedThreadPool(5);
public class FileProcessor {
public static void main(String[] args)
{
// run 5 threads
ExecutorService executor = Executors.newFixedThreadPool(5);
int i;
// get first and last file ID to process
int start = Integer.parseInt(args[0]);
int end = Integer.parseInt(args[1]);
for (i = start; i < end; i++)
{
final int finalId = i; // final necessary in anonymous class
executor.submit(new Runnable()
{
public void run()
{
processFile(finalId);
}
});
}
}
public static void processFile(int id)
{
//doing work here
}
}
公共类文件处理器{
公共静态void main(字符串[]args)
{
//运行5个线程
ExecutorService executor=Executors.newFixedThreadPool(5);
int i;
//获取要处理的第一个和最后一个文件ID
int start=Integer.parseInt(args[0]);
int end=Integer.parseInt(args[1]);
for(i=start;i
这是一个非常简单的多线程解决方案,它满足了我的需求。现在我想修复/改进它,因为我想我做错了(程序永远不会结束,占用的内存比它应该使用的更多等等)
可运行的对象的数量吗?如果我应该-我怎么做
如果要减少运行的线程数量,只需减少传递给固定线程池构造函数的大小。至于终止,请在executor服务上调用shutdown并等待终止。但这只会减少活动线程的数量,而不会减少循环中正在创建的可运行程序的数量。当您说程序永不结束,使用的内存超过了它应该使用的内存时,,这可能是由于许多原因,例如 1)
processFile()
可能正在执行一些繁重的I/O操作(或者)某些I/O数据被阻止
2) 如果存在任何公共数据对象共享,则可能存在潜在的死锁
您的线程逻辑本身,非常直接地使用ThreadPoolExecutor
,我相信问题在于processFile()
中的代码
由于已使用5初始化池,因此无论要创建多少个可能的线程,ThreadPoolExecutor
都会确保只有5个活动线程在执行该工作
因此,在本例中,我将更多地关注应用程序逻辑优化,而不是线程管理
如果您真的关心要创建多少可运行的
对象?然后,这就是应用程序需求和可用资源之间的权衡
若每个线程任务都是独立的,并且所有这些线程都有执行时间限制,那个么您可以在池中创建更多线程并添加更多资源
当您定义一个
PoolExecutor
时,在一个时间限制内有5个线程,并创建10000个线程,那么很明显,它们必须作为未来任务
在内存中等待,直到有一个线程可用 等等,等等。。。我认为我的for
循环在程序启动和后台处理“工作”时创建1000000个可运行对象。。。所以<代码>executor.submit(可运行)等待出现一些“空闲线程”?是。您创建了一个固定线程池,在本例中为5。您可以提交一百万个Runnable,但一次只能提交5个Runnable。当一个线程结束时,一个线程变为空闲线程,下一个可运行线程开始。。。我知道Runnable
是在应该的时候启动的,同时启动的Runnable是有限的。但我担心的是执行1000000次迭代的循环的,所以内存中大约有1000000个未启动可运行对象。搜索有关如何实现阻塞类型执行器的文章,以便在线程可用之前不会创建可运行对象,如果您担心内存中的所有对象都在等待空闲线程,那么我不确定它是否使用了太多RAM。我的processFile()方法非常简单。我只是对有1000000次迭代的大循环和该循环中的newrunnable()
感到困惑。所以我的线程代码没有问题吗?线程逻辑看起来不错。但是,如果您确实想提高性能,那么请定义一个实现Runnable
接口的类,并在其中包含processFile()
逻辑。并使用该新类的实例启动执行器。