views:

113

answers:

4

I am trying to Tune a thread which does the following:

A thread pool with just 1 thread [CorePoolSize =0, maxPoolSize = 1]

The Queue used is a ArrayBlockingQueue: http://download.oracle.com/javase/6/docs/api/java/util/concurrent/BlockingQueue.html#poll%28long,%20java.util.concurrent.TimeUnit%29

Quesize = 20

BackGround:
The thread tries to read a request and perform an operation on it.

HOWEVER, eventually the requests have increased so much that the thread is always busy and consume 1 CPU which makes it a resource hog.

What I want to do it , instead sample the requests at intervals and process them . Other requests can be safely ignored.

What I would have to do is put a sleep in "operation" function so that for each task the thread sleeps for sometime and releases the CPU.

Quesiton:
However , I was wondering if there is a way to use a queue which basically itself sleeps for sometime before it reads the next element. This would be ideal since sleeping a task in the middle of execution and keeping the execution incomplete just doesn't sound the best to me.

Please let me know if you have any other suggestions as well for the tasks

Thanks.

Edit: I have added a follow-up question here corrected the maxpool size to be 1 [written in a haste] .. thanks tim for pointing it out.

+1  A: 
erickson
+1  A: 

You could subclass ThreadPool and override beforeExecute to sleep for some time:

@Overrides
protected void beforeExecute(Thread t,
                         Runnable r){
    try{
       Thread.sleep( millis);  // will sleep the correct thread, see JavaDoc
    }
    catch (InterruptedException e){}

  }

But see AngerClown's comment about artificially slowing down the queue probably not being a good idea.

Thilo
Thanks, Thilo .. I think beforeExecute might do the trick . Will make the changes and accept the answer if it works fine :). Keeping the thread open in case there are few more ideas :)
p1
+1 for mentioning the beforeExecute method. People are sometimes so obsessed with the ExecutorService abstraction that they tend to forget the ThreadPoolExecutor implementation has some neat offerings too.
Tim Bender
I tried tinkering with this approach. Interestingly, @times the beforeExecute() is invoked and then immediately the task is executed without sleeping and then after the sleep time has elapsed the task is re-executed. I am using a thread pool and there is just one thread [see details in my question] .. am I missing something ??
p1
+1  A: 

This might not work for you, but you could try setting the executor's thread priority to low.

Essentially, create the ThreadPoolExecutor with a custom ThreadFactory. Have the ThreadFactory.newThread() method return Threads with a priority of Thread.MIN_PRIORITY. This will cause the executor service you use to only be scheduled if there is an available core to run it.

The implication: On a system that strictly uses time slicing, you will only be given a time slice to execute if there is no other Thread in the entire program with a greater priority asking to be scheduled. Depending on how busy your application really is, you might get scheduled every once in awhile, or you might not be scheduled at all.

Tim Bender
thanks .. I had considered this approach but I am afraid that it might starve my thread. Also, my thread is trying to sample data so I want a real world picture of what is happening ... doing this might skew the sample to only those periods where the CPU is low ...which defeats the purpose of having the thread. Also the individual task performed by thread is very small [but there are too many tasks] .. so I think sleeping might work better. Agreed ?
p1
Yes, agreed. I think Thilo's solution is best, which is why I up voted it.
Tim Bender
A: 

The reason the thread is consuming 100% CPU is because it is given more work than it can process. Adding a delay between tasks is not going to fix this problem. It is just make things worse.

Instead you should look at WHY your tasks are consuming so much CPU e.g. with a profiler and change them so that consume less CPU until you find that your thread can keep up and it no longer consumes 100% cpu.

Peter Lawrey