在Win7中运行多线程Java项目时出现的零星问题

在Win7中运行多线程Java项目时出现的零星问题,java,multithreading,threadpool,thread-priority,Java,Multithreading,Threadpool,Thread Priority,我正在做一个既需要内存又需要计算的项目。执行的很大一部分通过FixedThreadPool利用多线程。简言之我有1个线程用于从多个远程位置获取数据(使用URL连接),并用要分析的对象填充阻塞队列,还有n个线程用于拾取这些对象并运行分析编辑:参见下面的代码 现在,这个设置在我运行OpenSUSE 11.3的Linux机器上非常有用,但是一位同事正在运行Win7的非常类似的机器上测试它,在队列轮询中得到了超时的自定义通知(请参见下面的代码),实际上有很多。我一直在尝试监控她机器上的处理器使用情况,但

我正在做一个既需要内存又需要计算的项目。执行的很大一部分通过
FixedThreadPool
利用多线程。简言之我有1个线程用于从多个远程位置获取数据(使用URL连接),并用要分析的对象填充
阻塞队列
,还有n个线程用于拾取这些对象并运行分析编辑:参见下面的代码

现在,这个设置在我运行OpenSUSE 11.3的Linux机器上非常有用,但是一位同事正在运行Win7的非常类似的机器上测试它,在队列轮询中得到了超时的自定义通知(请参见下面的代码),实际上有很多。我一直在尝试监控她机器上的处理器使用情况,但软件似乎无法获得超过15%的CPU,而在我的机器上,处理器使用率达到了顶峰,正如我所预期的那样

那么,我的问题是,这是否是排队“挨饿”的迹象?是不是生产者线程没有得到足够的cpu时间?如果是这样的话,我如何给池中的一个特定线程更高的优先级

更新: 我一直在努力找出问题所在,但毫无乐趣。。。然而,我确实获得了一些新的见解

  • 使用JVisualVM评测代码的执行过程演示了一种非常奇特的行为。这些方法在短时间的CPU时间内被调用,其间几秒钟没有任何进展。对我来说,这意味着操作系统不知何故在这个过程中踩下了刹车

  • 禁用反病毒和备份守护进程不会对该问题产生任何重大影响

  • 通过任务管理器(adviced)更改java.exe(唯一实例)的优先级也不会更改任何内容。(尽管如此,我不能给java“实时”优先级,只能满足于“高”优先级)

  • 分析网络使用情况显示出良好的数据流入和流出,因此我猜测这不是瓶颈(虽然这是进程执行时间的一个相当大的部分,但我已经知道,并且与我在Linux机器上得到的数据百分比几乎相同)

关于Win7操作系统如何限制我的项目的cpu时间,有什么想法吗?如果不是操作系统,那么限制因素是什么?我想再次强调,这台机器在同一时间没有运行任何其他计算密集型,除了我的软件外,CPU上几乎没有负载。这让我快发疯了

编辑:相关代码

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);
      }

}
公共并发服务(数据集d、查询服务qserv、集合s){ 超时=3; this.qs=qserv; this.bq=qs.getQueue(); 这是d.ds=d; 此.analyzedObjects=s; this.drc=DebugRoutineContainer.getInstance(); this.start=false; int nbrofpocs=Runtime.getRuntime().availableProcessors(); poolSize=nbroc; 池=(ThreadPoolExecutor)执行器。newFixedThreadPool(池大小); setScoreLogStream(新的PrintStream(qs.getScoreLogFile()); } public void service()抛出InterruptedException{ 试一试{ 这是.ds.initDataset(); this.started=true; 执行(新查询操作(qs)); 对于(;;){ MyObject p=bq.poll(超时,时间单位:分钟); 如果(p!=null){ if(p.getId().equals(“0”)) 打破 提交(新的AnalysisAction(ds、p、AnalysizedObjects、qs.getKnownAssocs()); }否则 log(“等待对象时超时…”); } }捕获(例外情况除外){ 例如printStackTrace(); String exit_msg=“核心分析中出现意外错误,正在终止执行!”; }最后{ log(“--DEBUG:找到终止条件,已启动关机…”); drc.getMemoryInfo(true);//将meminfo转储到日志 pool.shutdown(); 整数分钟=2; int nCores=池大小; long totalTasks=pool.getTaskCount(), compTasks=pool.getCompletedTaskCount(), tasksRemaining=totalTasks-compTasks, 超时=分钟*任务维护/nCores; log(“--DEBUG:Shutdown已开始,线程池将在处理完所有对象后终止,”+ 或将在“+(totalTasks-1)”中的“+timeout+”分钟内超时…\n“+compTasks+” 到目前为止已分析对象,“+”平均处理时间为:+ getMeanProcTimeAsString()+“毫秒”); 池。等待终止(超时,时间单位。分钟); } }
queryaction
是一个简单的
Runnable
,它在指定的
QueryService
对象中调用数据采集方法,然后填充
阻塞队列
AnalysisAction
类对
MyObject
的单个实例执行所有的数字运算

我怀疑生产者线程获取/加载源数据的速度不够快。这可能不是CPU不足,而是与IO相关的问题。(不确定您的封锁队列为何超时)


让一个线程定期记录添加的任务数量和队列长度(例如,每5-15秒一次)这样的事情可能是值得的。

优先级没有帮助,因为问题不是决定谁获得宝贵资源的问题——资源利用率没有最大化。生产者线程得不到足够CPU时间的唯一方法是,它没有准备好运行。优先权没有帮助,因为问题不是问题

这台机器有多少芯?生产者线程可能正在全速运行,但仍然没有足够的CPU来运行。它也是
while (!terminate)
{
    synchronized (Producer.getLockObject())
    {
        try
        {
            //sleep (no processing at all)
            Producer.getLockObject().wait(); 
        }
        catch (Exceptions..)
    }

    MyObject p = Producer.getObjectFromQueue(); //this function should be synchronized

    //Analyse fetched data, and submit it to somewhere...   
}    
while (!terminate)
{
    MyObject newData = fetchData(); //fetch data from remote location

    addDataToQueueu(newData); //this should also be synchronized

    synchronized (getLockObject())
    {
        //wake up one thread to deal with the data
        getLockObject().notify();
    }
}