Thread timeout 적용 test 본문

Programming/Java

Thread timeout 적용 test

halatha 2011. 4. 12. 02:17
//	thread에 timeout 적용 test. timeout이 되는 것이 있고,
//	timeout이 되지 않고 일단 시작한 thread는 끝까지 실행하는 것이 있음
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class TestThreadPoolExecutor4 {
	private static final int	THREAD_NUM	=	5;
	private static final int	SLEEP_TIME_MILLISECONDS	=	3;
	private static final int	TIMEOUT_SECONDS	=	5;

	public static void testRunnable(final String name)	{
		final ThreadPoolExecutor	executor	=
						(ThreadPoolExecutor) Executors.newCachedThreadPool();
		for ( int i = 0; i < THREAD_NUM; ++i )	{
			final int	num	=	i;
			final class r implements Runnable	{	public void run()	{
				long	time0	=	System.nanoTime();
				for ( int i = 0; i < (num % 2 + 1) * 1000; ++i )	{
					try	{
						Thread.sleep(SLEEP_TIME_MILLISECONDS);
					}	catch (InterruptedException e) {
						throw new RuntimeException();
					}
				}
				long	time1	=	System.nanoTime();
				System.out.println(name + "\t" + num + " took " +
										(time1 - time0) / 1000 / 1000 + " ms");
			} };
			executor.execute(new r());
		}

		executor.shutdown();
		try	{
			if ( !executor.awaitTermination(TIMEOUT_SECONDS, TimeUnit.SECONDS) )
				executor.shutdownNow();
		} catch (InterruptedException e)	{
		} catch (RuntimeException e)	{	//	exception occurs here
		} finally {
			executor.shutdownNow();
		}
	}

	public static void testCallable(final String name)	{
		final ThreadPoolExecutor	executor	=
						(ThreadPoolExecutor) Executors.newCachedThreadPool();
		List<Callable<Object>>	list	=	new ArrayList<Callable<Object>>();
		for ( int i = 0; i < THREAD_NUM; ++i )	{
			final int	num	=	i;
			//			final class r implements Callable<Object>	{
			//				public Object call()	{
			//				long	time0	=	System.nanoTime();
			//				for ( int i = 0; i < (num % 2 + 1) * 1000; ++i )	{
			//					try	{
			//						Thread.sleep(SLEEP_TIME_MILLISECONDS);
			//					}	catch (InterruptedException e)	{
			//						e.printStackTrace();
			//						return	null;
			//					}
			//				}
			//				long	time1	=	System.nanoTime();
			//				System.out.println("Callable " + num + " took "
			//							+ (time1 - time0) / 1000 / 1000 + " ms");
			//				return	null;
			//			} };
			//			list.add(new r());
			list.add(new CallableClass<Object>(name, num, SLEEP_TIME_MILLISECONDS));
		}

		try	{
			executor.invokeAll(list, TIMEOUT_SECONDS, TimeUnit.SECONDS);
		} catch (InterruptedException e)	{	//	exception occurs here
		} catch (RuntimeException e)	{
		}
		executor.shutdown();
	}

	public static void awaitUninterruptibly(final long statusCheckMillis,
						final Future< ... futures) throws ExecutionException {
		ExecutionException lastEx = null;
		for (Future< future : futures) { 
			try {
				awaitUninterruptibly(statusCheckMillis, future);
			}
			catch (ExecutionException e) {
				// Wait for all futures, then throw the exception when all have finished
				lastEx = e;
			}
		}
		if (null != lastEx) { throw lastEx; }
	}
	public static void awaitUninterruptibly(final long statusCheckMillis,
						final Future< future) throws ExecutionException {
		if (null == future) { return; }
		long time0 = System.nanoTime();
		for (boolean done = false; !done; ) {
			try {
				future.get(statusCheckMillis, TimeUnit.MILLISECONDS);
				done = true;
			}
			catch (InterruptedException e)	{	Thread.interrupted();	}
			catch (ExecutionException e)	{	throw e;	}
			catch (TimeoutException e)	{	// Fall through
			}
			long time1 = System.nanoTime();
			final long waitMillis = (time1 - time0) / (1000 * 1000);
			if (!done && 0 < waitMillis || statusCheckMillis / 2 < waitMillis) {
				System.out.printf("Waited %dms with done=%b\n", waitMillis, done);
			}
		}
	}

	public static void testCallableWithCheckedTimeout(final String name)	{
		final ThreadPoolExecutor	executor	=
						(ThreadPoolExecutor) Executors.newCachedThreadPool();
		final Future< futures = (Future< new Future[THREAD_NUM];
		long	timeStart	=	System.nanoTime() + 5 * 1000 * 1000 * 1000;
		System.out.println("current time is\t" + timeStart);

		for ( int i = 0; i < THREAD_NUM; ++i )	{
			final int	num	=	i;
			futures[num]	=
				executor.submit(new CallableClass<Object>(name, num, SLEEP_TIME_MILLISECONDS));
		}

		for ( int i = 0; i < futures.length; ++i )
		{
			try {
				long	timeLeft	=	timeStart - System.nanoTime();
				futures[i].get(timeLeft, TimeUnit.MILLISECONDS);
			} catch (InterruptedException e) {
			} catch (ExecutionException e) {
			} catch (TimeoutException e) {	//	Exception occurs here
			} finally {
				futures[i].cancel(true);
			}
			timeStart	=	System.nanoTime() + 5 * 1000 * 1000 * 1000;
		}
		executor.shutdown();
	}

	private static final int	TIMEOUT_MILLISECONDS	=	TIMEOUT_SECONDS * 1000;
	public static void testCallableWithAwaitUninterruptibly(final String name)	{
		final ThreadPoolExecutor	executor	=
						(ThreadPoolExecutor) Executors.newCachedThreadPool();
		final Future< futures = (Future< new Future[THREAD_NUM];
		for ( int i = 0; i < THREAD_NUM; ++i )	{
			final int	num	=	i;
			futures[num]	=
				executor.submit(new CallableClass<Object>(name, num, SLEEP_TIME_MILLISECONDS));
		}

		try {
			awaitUninterruptibly(TIMEOUT_MILLISECONDS, futures);
		} catch (ExecutionException e) {
			System.out.println(name + "\tExecutionException\t" + e);
		}
	}

	public static void waitInterruptibly(final long statusCheckMillis,
						final Future< ... futures)
							throws ExecutionException, TimeoutException {
		ExecutionException lastEx = null;
		int	index	=	0;
		for (Future< future : futures) { 
			try {
				waitInterruptibly(statusCheckMillis, future, index++);
			}
			catch (ExecutionException e) {
				// Wait for all futures, then throw the exception when all have finished
				lastEx = e;
			}
			catch (TimeoutException e)	{
				throw e;
			}
		}
		if (null != lastEx) { throw lastEx; }
	}
	public static void waitInterruptibly(final long statusCheckMillis,
						final Future< future, final int index)
							throws ExecutionException, TimeoutException {
		if (null == future) { return; }
		long time0 = System.nanoTime();
		for (boolean done = false; !done; ) {
			try {
				future.get(statusCheckMillis, TimeUnit.MILLISECONDS);
				done = true;
			}
			catch (InterruptedException e)	{	Thread.interrupted();	}
			catch (ExecutionException e)	{	throw e;	}
			catch (TimeoutException e) {
				long time1 = System.nanoTime();
				final long waitMillis = (time1 - time0) / (1000 * 1000);
				if (!done && 0 < waitMillis || statusCheckMillis / 2 < waitMillis) {
					System.out.printf("%d Waited %dms with done=%b\n",
									index, waitMillis, done);
				}
				throw e;
			} finally {
				long time1 = System.nanoTime();
				System.out.printf("%d Finally took %d\n",
									index, (time1 - time0) / (1000 * 1000));
			}
		}
	}

	public static void testCallableWithWaitInterruptibly(final String name)	{
		final ThreadPoolExecutor	executor	=
						(ThreadPoolExecutor) Executors.newCachedThreadPool();
		final Future< futures = (Future< new Future[THREAD_NUM];
		for ( int i = 0; i < THREAD_NUM; ++i )	{
			final int	num	=	i;
			futures[num]	=
				executor.submit(new CallableClass<Object>(name, num, SLEEP_TIME_MILLISECONDS));
		}

		try {
			waitInterruptibly(TIMEOUT_MILLISECONDS, futures);
		} catch (ExecutionException e) {
		} catch (TimeoutException e) {
		}
	}

	public static void testCallableWithTimeoutLoop(final String name)	{
		long	time0	=	System.nanoTime();

		final ThreadPoolExecutor	executor	=
						(ThreadPoolExecutor) Executors.newCachedThreadPool();
		final Future< futures = (Future< new Future[THREAD_NUM];
		for ( int i = 0; i < THREAD_NUM; ++i )	{
			final int	num	=	i;
			futures[num]	=
				executor.submit(new CallableClass<Object>(name, num, SLEEP_TIME_MILLISECONDS));
		}

		executor.shutdown();
		try {
			executor.awaitTermination(5, TimeUnit.SECONDS);
		} catch (InterruptedException e) {
		} finally {
			executor.shutdownNow();
		}
		while ( false == executor.isTerminated() )
		{
			long	time1	=	System.nanoTime();
			System.out.println(name + "\t" + (time1 - time0) / 1000 / 1000 + " ms");
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
			}
		}
	}

	public static void testCallableWithFutureGetTimeout(final String name)	{
		final ThreadPoolExecutor	executor	=
						(ThreadPoolExecutor) Executors.newFixedThreadPool(64);
		final Future< futures = (Future< new Future[THREAD_NUM];
		for ( int i = 0; i < THREAD_NUM; ++i )	{
			final int	num	=	i;
			futures[num]	=
				executor.submit(new CallableClass<Object>(name, num, SLEEP_TIME_MILLISECONDS));
		}

		executor.shutdown();
		for ( int i = 0; i < futures.length; ++i )
		{
			try {
				futures[i].get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
			} catch (InterruptedException e) {
			} catch (ExecutionException e) {
			} catch (TimeoutException e) {	//	Exception occurs here
			} finally {
				futures[i].cancel(true);
			}
		}
	}

	public static void main(final String[] args)	{
		long    time0, time1;
		Method[]    methodArray =  
						new TestThreadPoolExecutor4().getClass().getDeclaredMethods();
		for ( Method m : methodArray )
		{
			if ( true == m.getName().startsWith("test") )
			{
				try {
					time0	=	System.nanoTime();
					m.invoke(null, m.getName());
					time1	=	System.nanoTime();
					System.out.println(">>>>>>>>>>\t" + m.getName() +
									" took " + (time1 - time0) / 1000 / 1000 + " ms\n\n");
				} catch (IllegalArgumentException e) {
				} catch (IllegalAccessException e) {
				} catch (InvocationTargetException e) {
				}
			}
		}
	}
}

class CallableClass<T> implements Callable<T>
{
	final String	methodName;
	final int	num;
	final int	sleepTimeMillis;

	public CallableClass(String methodName, int num, int sleepTimeMillis)
	{
		this.methodName	=	methodName;
		this.num	=	num;
		this.sleepTimeMillis	=	sleepTimeMillis;
	}

	public T call()
	{
		long	time0	=	System.nanoTime();
		for ( int i = 0; i < (num % 2 + 1) * 1000; ++i )	{
			try	{
				Thread.sleep(sleepTimeMillis);
			}	catch (InterruptedException e)	{
				e.printStackTrace();
				return	null;
			}
		}
		long	time1	=	System.nanoTime();
		System.out.println(methodName + "\t" + num + " took " + (time1 - time0) / 1000 / 1000 + " ms");
		return	null;
	} 
}
Comments