在Win7中运行多线程Java项目时的零星问题
我正在研究一个既记忆又计算密集的项目.执行的很大一部分利用了FixedThreadPool的多线程.简而言之;我有一个线程用于从多个远程位置(使用URL连接)获取数据,并使用要分析的对象填充BlockingQueue,以及选择这些对象并运行分析的n个线程.编辑:见下面的代码 现在这个设置就像运行OpenSUSE 11.3的Linux机器上的魅力一样,但是一位同事在运行Win7的非常类似的机器上测试它,在队列轮询(见下面的代码)中得到了超时的定制通知,其实很多.我一直在尝试监控她的机器上的处理器使用情况,而且似乎该软件不会超过15%的CPU,而在我的机器上,处理器使用率正好按照我的意图. 我的问题是,这能否成为排队的“饥饿”的标志?可能这样,生产者线程没有足够的cpu时间?如果是这样,我如何去给予一个特定的线程池更高的优先级? 更新: >使用JVisualVM分析代码的执行情况,显示出非常特殊的行为.这些方法以短时间的CPU时间来进行调用,几秒钟之间没有进展.这对我来说意味着操作系统在某种程度上正在制动过程中. 有关Win7 OS如何将cpu时间限制在我的项目的任何想法?如果不是操作系统,可能是什么限制因素?我想再次强调,该机器不会同时运行任何其他计算密集型,除了我的软件之外,cpus几乎没有任何负载.这让我疯狂了 编辑:相关代码 public ConcurrencyService(Dataset d,QueryService qserv,Set<MyObject> s){ timeout = 3; this.qs = qserv; this.bq = qs.getQueue(); this.ds = d; this.analyzedObjects = s; this.drc = DebugRoutineContainer.getInstance(); this.started = false; int nbrOfProcs = Runtime.getRuntime().availableProcessors(); poolSize = nbrOfProcs; pool = (ThreadPoolExecutor) Executors.newFixedThreadPool(poolSize); drc.setScoreLogStream(new PrintStream(qs.getScoreLogFile())); } public void serve() throws InterruptedException { try { this.ds.initDataset(); this.started = true; pool.execute(new QueryingAction(qs)); for(;;){ MyObject p = bq.poll(timeout,TimeUnit.MINUTES); if(p != null){ if (p.getId().equals("0")) break; pool.submit(new AnalysisAction(ds,p,analyzedObjects,qs.getKnownAssocs())); }else drc.log("Timed out while waiting for an object..."); } } catch (Exception ex) { ex.printStackTrace(); String exit_msg = "Unexpected error in core analysis,terminating execution!"; }finally{ drc.log("--DEBUG: Termination criteria found,shutdown initiated.."); drc.getMemoryInfo(true); // dump meminfo to log pool.shutdown(); int mins = 2; int nCores = poolSize; long totalTasks = pool.getTaskCount(),compTasks = pool.getCompletedTaskCount(),tasksRemaining = totalTasks - compTasks,timeout = mins * tasksRemaining / nCores; drc.log("--DEBUG: Shutdown commenced,thread pool will terminate once all objects are processed," + "or will timeout in : " + timeout + " minutes... \n" + compTasks + " of " + (totalTasks -1) + " objects have been analyzed so far," + "mean process time is: " + drc.getMeanProcTimeAsString() + " milliseconds."); pool.awaitTermination(timeout,TimeUnit.MINUTES); } } QueryingAction类是一个简单的Runnable,它调用指定的QueryService对象中的数据采集方法,然后填充BlockingQueue. AnalysisAction类对MyObject的单个实例执行所有的数字处理. 我怀疑生产者线程没有得到/加载源数据足够快.这可能不是缺乏CPU,而是与IO相关的问题. (不知道为什么你在BlockingQueue上有超时)可能值得有一个线程周期性地记录添加的任务数量和队列的长度(例如每5-15秒) (编辑:ASP站长网) |