简体   繁体   中英

Java Threads and high cpu usage

I've done some search here and couldn't find an answer, so I think it's better to ask. I'm running a little bit expensive algorithm in a simple Java swing application. Let me describe the structure:

In my JPanel run() method:

public void run() {
    while(true) {
        Algorithm alg = new Algorithm(signal);
        new Thread(alg).start();

        //Wait for algorithm to finish 
        signal.await(alg);

        updateInterface();

        Thread.sleep(60L);
    }
}

Algorithm loops through the pixels of a .JPG file, then loops through another large Integer array (length ~ 12000) and returns. There are very no extra expensive calculationslot. I call Thread.sleep(60L) in the Algorithm run() method also.

The udpateInterface() method is very fast, just draw some java.awt.Polygon objects.

Even though I'm calling Thread.sleep(60L) , the CPU usage is about 160% on my Mac Book (2.4 GHz Intel Core 2 Duo, Mem 4GB 1067).

Is there a way I can run this without melting my computer? I'm using CountDownLatch as a wait notify mechanism.

Thanks!

I would use the following pattern to schedule a repeating task.

private ScheduledExecutorService executorService = null;

public void start() {
    if (executorService != null && !executorService.isShutdown()) return;

    executorService = Executors.newSingleThreadScheduledExecutor();
        executorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                Algorithm alg = new Algorithm(signal);
                alg.run();
                updateInterface();
            }
        }, 0, 60, TimeUnit.MILLISECONDS);
}

public void stop() {
    if (executorService != null)
        executorService.shutdown();
}

160% CPU usage is relative to a single core of your machine -- that is, the maximum possible on your machine is 200%, because it has two cores. You're not melting your processor.

There's no point starting another thread if all you're going to do afterward is make the current thread wait for the other one to finish. You might as well just run the algorithm in the thread you already have; either way, you won't proceeed to updateInterface() until the algorithm is done.

As others have pointed out, after the algorithm finishes and you update the UI, you're only waiting 60 milliseconds before starting the algorithm again. It sounds like your program is spending most of its time running the algorithm. That's fine if you need it to update the screen that quickly, but you might consider using a longer delay otherwise.

Also, you're starting a new thread each time through the loop. Does that thread run the algorithm once and then terminate, or does it run the algorithm in a loop? If you have a loop starting threads that are each long-running CPU-intensive loops, you might be accidentally running many copies of the algorithm at once. If you expect the algorithm thread to terminate after it signals you, you should join() it to make sure.

How much wait do you want? If you want to wait for 60 seconds, you should use 60000L, as the time is specified in milliseconds.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM