首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Win7中运行多线程Java项目中的零星问题

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

Stack Overflow用户
提问于 2011-12-19 10:59:38
回答 8查看 1.3K关注 0票数 12

我正在做一个内存和计算密集型的项目。执行的很大一部分是利用FixedThreadPool的多线程。简而言之,我有一个线程,用于从多个远程位置(使用URL连接)获取数据,并使用要分析的对象填充BlockingQueue,以及选择这些对象并运行分析的n个线程。编辑:参见下面的代码

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

我的问题是,这是否“饥饿”的迹象?会不会是因为生产者线程没有足够的cpu时间?如果是这样的话,我如何为池中的一个特定线程赋予更高的优先级?

更新:我一直在努力找出问题,没有joy.然而,我确实获得了一些新的见解。

  • 使用JVisualVM分析代码的执行会显示出一种非常奇特的行为。这些方法是在短时间的CPU时间内调用的,其间没有任何进展。对我来说,这意味着操作系统在某种程度上踩到了制动器。
  • 禁用防病毒和备份守护进程对此问题没有任何重大影响。
  • 通过任务管理器(建议的java.exe )更改java.exe(唯一实例)的优先级也不会改变任何事情。(话虽如此,我不能给予java“实时”优先权,必须满足于“高”prio)
  • 分析网络使用情况会显示出良好的进出数据流,因此我猜想这不是瓶颈(虽然它是进程执行时间的相当一部分,但我已经知道了,并且与我在Linux机器上得到的数据的百分比差不多)。

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

编辑:相关代码

代码语言:javascript
复制
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对象中调用数据采集方法,然后填充BlockingQueueAnalysisAction类为MyObject的单个实例执行所有的数字处理。

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2012-02-02 18:10:56

因此,经过数周的篡改,在代码和其他类型的痛苦中挣扎,我想我有一个突破,“片刻的清晰”,如果你愿意的话.

我设法证明了这个程序可以在我的Linux机器上表现出同样的缓慢行为,并且确实可以在有问题的Win-7机器上运行完全节流阀。问题的症结似乎是系统/缓存文件的某种损坏,这些文件用于存储以前查询的结果,并且总体上加快了分析的速度。你会喜欢讽刺的,在这种情况下,他们似乎是极慢分析的原因。回想起来,我应该知道(拉奥卡姆剃刀).

我仍然不知道腐败是如何发生的,但至少它可能与不同的操作系统无关。然而,使用我机器上的系统文件只会使Win7主机上的输出增加约40%。对进程进行更多的分析还发现,奇怪的是,在Win7上有更多的GC活动,这显然花费了大量的CPU时间来处理数字。让-Xmx2g处理过多的垃圾收集,进程的CPU使用率高达95%-96%,线程运行平稳。

现在我已经回答了我最初的问题,我不得不说,在Linux环境下,总体java响应性肯定更好,即使没有分配更多堆内存,在后台运行广泛分析时,我也可以轻松地执行多任务。在Win-7,e.x中,事情并不顺利。一旦分析以全速进行,调整GUI的大小是非常缓慢的。

感谢所有的答复,我很抱歉对部分误导性问题的描述。我只是分享了我在尽我最大能力进行调试时发现的情况。不管怎样,我相信赏金是交给彼得·劳瑞的,因为他很早就指出了一个I/O问题,是他关于伐木线的建议最终使我找到了答案。

票数 1
EN

Stack Overflow用户

发布于 2011-12-19 11:03:55

我怀疑生产者线程获取/加载源数据的速度不够快。这可能不是缺少CPU,而是与IO相关的问题。(不知道为什么BlockingQueue上有超时时间)

可能值得有一个线程定期记录添加的任务数和队列长度(例如每5-15秒)。

票数 3
EN

Stack Overflow用户

发布于 2012-02-01 15:22:02

因此,如果我正确理解了您的问题,您将有一个线程来获取数据,多个线程来分析所获取的数据。您的问题是线程没有正确地同步以一起运行并充分利用处理器。

你有一个尖锐的生产者-消费者的单一生产者和几个消费者问题。我建议您稍加修改代码,使之有几个独立的使用者线程,这些线程总是等待资源可用,然后才能运行。这样可以保证最大限度地使用处理器。

消费者线索:

代码语言:javascript
复制
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...   
}    

出厂线:

代码语言:javascript
复制
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();
    }
}

您可以看到,这样,您的线程总是在执行有用的工作或休眠。这只是用来举例说明的草案代码。请参阅这里的更多解释:to.shtmlhttp://www.java-samples.com/showtutorial.php?tutorialid=306

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8560319

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档