//========================================================================
//Copyright 2004-2008 Mort Bay Consulting Pty. Ltd.
//------------------------------------------------------------------------
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//http://www.apache.org/licenses/LICENSE-2.0
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
//========================================================================
package org.mortbay.thread;
import java.util.Random;
import junit.framework.TestCase;
public class ThreadPoolTest extends TestCase
{
int _jobs;
long _result;
volatile long _sleep=100;
Runnable _job = new Runnable()
{
public void run()
{
try
{
Thread.sleep(_sleep);
}
catch(Exception e)
{
e.printStackTrace();
}
long t = System.currentTimeMillis()%10000;
long r=t;
for (int i=0;i<t;i++)
r+=i;
synchronized(ThreadPoolTest.class)
{
_jobs++;
_result+=r;
}
}
};
public void testQueuedThreadPool() throws Exception
{
_sleep=100;
QueuedThreadPool tp= new QueuedThreadPool();
tp.setMinThreads(5);
tp.setMaxThreads(10);
tp.setMaxIdleTimeMs(1000);
tp.setSpawnOrShrinkAt(2);
tp.setThreadsPriority(Thread.NORM_PRIORITY-1);
tp.start();
Thread.sleep(500);
assertEquals(5,tp.getThreads());
assertEquals(5,tp.getIdleThreads());
tp.dispatch(_job);
tp.dispatch(_job);
assertEquals(5,tp.getThreads());
assertEquals(3,tp.getIdleThreads());
Thread.sleep(500);
assertEquals(5,tp.getThreads());
assertEquals(5,tp.getIdleThreads());
for (int i=0;i<100;i++)
tp.dispatch(_job);
assertTrue(tp.getQueueSize()>10);
assertTrue(tp.getIdleThreads()<=1);
Thread.sleep(2000);
assertEquals(0,tp.getQueueSize());
assertTrue(tp.getIdleThreads()>5);
int threads=tp.getThreads();
assertTrue(threads>5);
Thread.sleep(1500);
assertTrue(tp.getThreads()<threads);
}
public void testQueuedThreadPoolShrink() throws Exception
{
QueuedThreadPool tp= new QueuedThreadPool();
tp.setMinThreads(2);
tp.setMaxThreads(10);
tp.setMaxIdleTimeMs(400);
tp.setSpawnOrShrinkAt(2);
tp.setThreadsPriority(Thread.NORM_PRIORITY-1);
tp.start();
Thread.sleep(100);
assertEquals(2,tp.getThreads());
assertEquals(2,tp.getIdleThreads());
_sleep=200;
tp.dispatch(_job);
tp.dispatch(_job);
for (int i=0;i<20;i++)
tp.dispatch(_job);
Thread.sleep(100);
assertEquals(10,tp.getThreads());
assertEquals(0,tp.getIdleThreads());
_sleep=1;
for (int i=0;i<500;i++)
{
tp.dispatch(_job);
Thread.sleep(10);
if (i%100==0)
{
System.err.println(i+" threads="+tp.getThreads()+" idle="+tp.getIdleThreads());
}
}
System.err.println("500 threads="+tp.getThreads()+" idle="+tp.getIdleThreads());
assertEquals(2,tp.getThreads());
assertEquals(2,tp.getIdleThreads());
}
public void testStress() throws Exception
{
_sleep=100;
boolean stress=Boolean.getBoolean("STRESS");
QueuedThreadPool tp= new QueuedThreadPool();
tp.setMinThreads(stress?240:24);
tp.setMaxThreads(stress?250:25);
tp.setMaxIdleTimeMs(100);
tp.start();
tp.setMinThreads(stress?90:9);
final int[] count={0};
final Random random = new Random(System.currentTimeMillis());
int loops = stress?16000:1600;
try
{
for (int i=0;i<loops;)
{
int burst=random.nextInt(100);
for (int b=0;b<burst && i<loops; b++)
{
if (i%20==0)
System.err.print('.');
if (i%1600==1599)
System.err.println();
if (i==1000)
tp.setMinThreads(10);
if (i==10000)
tp.setMaxThreads(20);
i++;
tp.dispatch(new Runnable()
{
public void run()
{
int s=random.nextInt(40)+10;
try
{
Thread.sleep(s);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
finally
{
synchronized (ThreadPoolTest.this)
{
count[0]++;
}
}
}
});
}
Thread.sleep(random.nextInt(100));
}
int waits=0;
while(true)
{
synchronized (ThreadPoolTest.this)
{
if (loops==count[0] || waits++>10)
break;
}
Thread.sleep(500);
}
synchronized (ThreadPoolTest.this)
{
assertEquals(loops,count[0]);
}
tp.stop();
Thread.sleep(100);
}
catch (Exception e)
{
e.printStackTrace();
assertTrue(false);
}
}
public void testMaxStopTime() throws Exception
{
QueuedThreadPool tp= new QueuedThreadPool();
tp.setMaxStopTimeMs(500);
tp.start();
tp.dispatch(new Runnable(){
public void run () {
while (true) {
try {
Thread.sleep(10000);
} catch (InterruptedException ie) {}
}
}
});
long beforeStop = System.currentTimeMillis();
tp.stop();
long afterStop = System.currentTimeMillis();
assertTrue(tp.isStopped());
assertTrue(afterStop - beforeStop < 1000);
}
}