thread pool with CachedThreadPool

P

Philipp Kraus

Hello,

I try to use the Executors.newCachedThreadPool to create a pool with runnables:

class myPool
{

private boolean running = false;
ExecutorService pool = Executors.newCachedThreadPool();

public void start()
{
running = true;
for(int i=0; i < poolsize; i++)
pool.submit( new myWorker(this) );
}

public void stop()
{
running = false;
pool.shutdown();
try {
m_pool.awaitTermination(5, TimeUnit.SECONDS);
} catch (InterruptedException ex) {}
}

public boolean isRunning()
{
return running;
}

}

class myWortker implements Runnable
{
private myPool master = null;

public myWorker( myPool pool ) { master = pool; }

public void run()
{
while(master.isRunning)
{
do a lot of work
}
}

I have removed any synchronized calls to show the basic structure only.
If I run
myPool pool = new myPool();
pool.start()
pool.stop();

everything works fine, all workers are started and all workers shut
down. If I call after the stop() the start()
method again I get an exception
"java.util.concurrent.RejectedExecutionException".

IMHO start() should create all workers and stop() should shutdown the
pool and a new start call should create the pool with workers again.
Did I missing anything? I think I don't understand the pool logic in a
correct manner. Can anybody explain me my mistake?

Thanks a lot

Phil
 
J

Joerg Meier

If I run
myPool pool = new myPool();
pool.start()
pool.stop();
everything works fine, all workers are started and all workers shut
down. If I call after the stop() the start()
method again I get an exception
"java.util.concurrent.RejectedExecutionException".

That is because you have shut the pool down. Once a pool is shut down, no
more tasks can be submitted. And it would not make any sense to submit new
tasks to a pool that has been ordered not to execute new tasks. There is,
as far as I know, no way to revert the state of a pool back to running once
it enters shutdown mode.

If you want a pauseable pool, you might want to look at the API
documentation for ThreadPoolExecutor, which has a simple example for
extending the class:

<http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html>

Search for "For example, here is a subclass that adds a simple pause/resume
feature:".

Liebe Gruesse,
Joerg
 
P

Philipp Kraus

On Tue, 15 Apr 2014 10:47:02 +0200, Philipp Kraus wrote:

If you want a pauseable pool, you might want to look at the API
documentation for ThreadPoolExecutor, which has a simple example for
extending the class:

<http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html>


Search for "For example, here is a subclass that adds a simple pause/resume
feature:".

Thanks imho the "shutdown" should be the "pause" option. I think it was
a missunderstanding of the shutdown call

Phil
 
D

Daniel Pitts

Thanks imho the "shutdown" should be the "pause" option. I think it was
a missunderstanding of the shutdown call

Why pause? All your tasks have completed, so all the "workers" that may
still be running are "paused" automatically, awaiting a signal to start
up again.

"Threads" with nothing to do take up very little CPU. They may take up
memory or other resources, but they can be made to do nothing until
called for.
 
R

Robert Klemme

"Threads" with nothing to do take up very little CPU. They may take up
memory or other resources, but they can be made to do nothing until
called for.

What do they take CPU for other than that negligible amount of time the
kernel takes for administering them? I'd say for all practical purposes
you can assume a blocked thread to take up zero %CPU. Or am I missing
something?

Cheers

robert
 
J

Josip Almasi

What do they take CPU for other than that negligible amount of time the
kernel takes for administering them? I'd say for all practical purposes
you can assume a blocked thread to take up zero %CPU. Or am I missing
something?

Blocked thread itself spends no cpu time.
Running thread may spend some more cpu time though, for lock checks.
Real issue is flushing pipeline to ensure cache coherency among all cpu
cores.
So, more 'synchronized' statements your single running thread
encounters, more cpu stalls. It's not really 'taking' cpu time, it's
wasting it.
I have to admit, intel pipeline is complete mistery to me:)
But that's why have atomics and other non-blocking thread-safe magic.

Regards...
 
R

Robert Klemme

Blocked thread itself spends no cpu time.
Running thread may spend some more cpu time though, for lock checks.
Real issue is flushing pipeline to ensure cache coherency among all cpu
cores.
So, more 'synchronized' statements your single running thread
encounters, more cpu stalls. It's not really 'taking' cpu time, it's
wasting it.

I don't think this applies. We were talking about threads idling in the
pool.
I have to admit, intel pipeline is complete mistery to me:)
But that's why have atomics and other non-blocking thread-safe magic.

The straightforward implementation will block them so there is no CPU
consumption. Custom implementations of thread pools may employ spin
locks but that usually is only done if you expect to always have work
for all threads.

Cheers

robert
 
K

Kevin McMurtrie

Robert Klemme said:
I don't think this applies. We were talking about threads idling in the
pool.


The straightforward implementation will block them so there is no CPU
consumption. Custom implementations of thread pools may employ spin
locks but that usually is only done if you expect to always have work
for all threads.

Cheers

robert

Sun's thread pools are garbage because some of the API is not logically
possible to implement. I don't recommend starting, stopping, or
resizing except when absolutely necessary. Create a large fixed size
pool and leave it running.


None of the Sun thread pools can garbage collect if left running or if
shutdown() malfunctions. No, you can't create a ThreadPoolExecutor with
a minimum size of zero. See the next bug...

All Sun executors might not create new threads as needed. If new
threads are required for existing threads to finish a task, it will
eventually deadlock. A core size of zero may cause tasks to not execute
until new tasks are submitted.

ThreadPoolExecutor round robins threads so excess threads may never hit
their timeout as long as even one task is regularly running.

ThreadPoolExecutor prefers to create a new thread rather than wait for
an existing thread to finish. Creating a new thread is expensive and it
prevents other threads from finishing. As a result, a rapid task
injections always drive ThreadPoolExecutor to the maximum thread count,
or OOM.

ScheduledExecutorService has a bug in shutdown() that spins loops until
all future tasks have completed, no matter how far out that may be. It
must not be used.

Interface ScheduledFuture/Delayed can not be implemented safely.
Delayed.getDelay(TimeUnit) produces an arbitrarily changing value that
prevents compareTo(Delayed) from being stable. An unstable compareTo()
fatally corrupts the task queue. An unsafe cast to an object producing
an absolute time is needed (Sun does this).
 
J

Josip Almasi

[snip]

Probably so.
But, see, it's not just 'small ammount of kernel time', issues go all
the way to cpu design.
Sun's thread pools are garbage

[snip]

Dang.
Thanks Kevin, you possibly saved me a lot of time.

Regards...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,528
Members
45,000
Latest member
MurrayKeync

Latest Threads

Top