How to make threads share CPU (almost) equally?

T

TheOne

I am developing a multithreaded application. I have a main thread
(default java main thread)
which creates and starts n number of new "worker threads" whose
priority is set to MAX_PRIORITY at the
time of creation. It then calls join() on each of these threads.

The run method of these threads is something like this:
(I am giving steps here instead of actual code for space reasons)

1. //get some work to do

2. //request data over the network(IO bound operation)

3. //Do some calculations on the data (CPU bound operation)

4. //update some shared data structures

Now I want the IO operations(2) of one thread going simultaneouly
with calculations(3) of another thread (thats the whole purpose of
multithreading !!!)
But it does not happen. The first thread created (thread-0) does not
give up
CPU.

I tried lowering current thread's priority to MIN_PRIORITY before
it enters step(2) and reverting it back to MAX_PRIORITY before step(3)
but it was of no use too.

One thing I did not try (and would not like to write code for) is to
make
the currently running thread sleep for a brief amount of time between
each IO request in
step(2). I feel that it is not a proper way of making threads share CPU
equally.
Am I right?

Do you have some good suggestions on how to make ensure that one thread
does not
monopolize CPU time even when it is waiting for IO ?

I am using Java 1.5 on Windows XP platform.
 
K

Kevin McMurtrie

TheOne said:
I am developing a multithreaded application. I have a main thread
(default java main thread)
which creates and starts n number of new "worker threads" whose
priority is set to MAX_PRIORITY at the
time of creation. It then calls join() on each of these threads.

The run method of these threads is something like this:
(I am giving steps here instead of actual code for space reasons)

1. //get some work to do

2. //request data over the network(IO bound operation)

3. //Do some calculations on the data (CPU bound operation)

4. //update some shared data structures

Now I want the IO operations(2) of one thread going simultaneouly
with calculations(3) of another thread (thats the whole purpose of
multithreading !!!)
But it does not happen. The first thread created (thread-0) does not
give up
CPU.

I tried lowering current thread's priority to MIN_PRIORITY before
it enters step(2) and reverting it back to MAX_PRIORITY before step(3)
but it was of no use too.

One thing I did not try (and would not like to write code for) is to
make
the currently running thread sleep for a brief amount of time between
each IO request in
step(2). I feel that it is not a proper way of making threads share CPU
equally.
Am I right?

Do you have some good suggestions on how to make ensure that one thread
does not
monopolize CPU time even when it is waiting for IO ?

I am using Java 1.5 on Windows XP platform.

It sounds like a synchronization problem. Halt one thread in a debugger
during step 3 and see if the other thread may continue or if it gets
blocked. A JVM stack dump will also show locks but it can be difficult
to time it.
 
F

Frank

TheOne said:
I am developing a multithreaded application. I have a main thread
(default java main thread)
which creates and starts n number of new "worker threads" whose
priority is set to MAX_PRIORITY at the
time of creation.

Above normal priority might be appropriate for IO or very critical and
extremely short-lived tasks.
It doesn't make your computer any faster, you'll just be stealing cpu
time from other, perhaps more important, tasks.
It then calls join() on each of these threads.

Hmm.. Probably ok if all the threads really are already started and you
don't need to do anything else from your main thread till all the
workers are finished. I assume joining on a finished thread will just
return immidiately.
The run method of these threads is something like this:
(I am giving steps here instead of actual code for space reasons)

1. //get some work to do

2. //request data over the network(IO bound operation)

3. //Do some calculations on the data (CPU bound operation)

4. //update some shared data structures

Now I want the IO operations(2) of one thread going simultaneouly
with calculations(3) of another thread (thats the whole purpose of
multithreading !!!)
But it does not happen. The first thread created (thread-0) does not
give up
CPU.
Hmm..

I tried lowering current thread's priority to MIN_PRIORITY before
it enters step(2) and reverting it back to MAX_PRIORITY before step(3)
but it was of no use too.

Really? Try it the other way around...
One thing I did not try (and would not like to write code for) is to
make
the currently running thread sleep for a brief amount of time between
each IO request in
step(2). I feel that it is not a proper way of making threads share CPU
equally.
Am I right?

Do you have some good suggestions on how to make ensure that one thread
does not
monopolize CPU time even when it is waiting for IO ?

No reason to call sleep for a thread doing blocking IO.

If it's non-blocking OTOH, you want to suspend it for a while when
there's no input ready, or it will just burn cycles checking for input
over and over.


And do go over your synchronization approach, checking for deadlocks.
 
M

Marcin Grunwald

TheOne said:
I am developing a multithreaded application. I have a main thread
(default java main thread)
which creates and starts n number of new "worker threads" whose
priority is set to MAX_PRIORITY at the
time of creation. It then calls join() on each of these threads.

The run method of these threads is something like this:
(I am giving steps here instead of actual code for space reasons)

1. //get some work to do

2. //request data over the network(IO bound operation)

3. //Do some calculations on the data (CPU bound operation)

4. //update some shared data structures

Now I want the IO operations(2) of one thread going simultaneouly
with calculations(3) of another thread (thats the whole purpose of
multithreading !!!)
But it does not happen. The first thread created (thread-0) does not
give up
CPU.

Maybe you just have a simple bug:
- are you sure you create new threads (invoke start() not run() :) )
- check how much time whole operation and each step takes
- maybe whole operation is so short that JVM doesn't switch to another
thread,
- maybe step 2 takes 99% of whole operation - so there is no profit from
many threads,
- maybe you have make mistake in loop operation - without blocking
operation and that takes whole CPU,
- maybe you call join() between creating threads instead of after creating
every thread,
- and many other simple reasons.

It's hard to say without code.
Use profiler to check what is really going on, or at least log every step
with timestamp.
 

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

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top