Thread Pool Executor Example (J2SE)

The code demonstrates using the thread pool for tasks execution in J2SE, Sun documentation is here.
/**
 * @author Vladimir Lysyy
 */

package net.bobah.concurrent.demo;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
//import java.util.concurrent.ExecutorService;
//import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class PoolDemo {
  private static class RejectedHandler implements RejectedExecutionHandler {
    @Override
    public void rejectedExecution(Runnable arg0, ThreadPoolExecutor arg1) {
      // TODO Auto-generated method stub
      System.err.println(Thread.currentThread().getName() + " execution rejected: " + arg0);     
    }
  }

  private static class Task implements Runnable {
    private static SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");
    private String name;
    private Date created;

    public Task(String name) {
      this.name = name;
      this.created = new Date();
    }
   
    @Override
    public void run() {
      final boolean wantOverflow = true;
      System.out.println(Thread.currentThread().getName() + " executing " + this);
      try {
        Thread.sleep(wantOverflow ? 50 : 10);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      System.out.println(Thread.currentThread().getName() + " executed " + this);
    }

    @Override
    public String toString() {
      return name + ", created " + fmt.format(created);
    }

  }

  public static void main(String[] args) throws InterruptedException {
    final boolean wantExceptionOnReject = false;

//    // fixed pool, unlimited queue
//    ExecutorService service = Executors.newFixedThreadPool(10 /* size */);
//    ThreadPoolExecutor executor = (ThreadPoolExecutor) service;

    // fixed pool fixed queue
    BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(100, true);
    ThreadPoolExecutor executor = new ThreadPoolExecutor(
      10, // core size
      20, // max size
      1, // keep alive time
      TimeUnit.MINUTES, // keep alive time units
      queue // the queue to use
    );

    // set rejected execution handler
    // or catch exception from executor.execute (see below)
    if (!wantExceptionOnReject) executor.setRejectedExecutionHandler(new RejectedHandler());

    for(long i = 0; ; ++i) {
      Task t = new Task(String.valueOf(i));
      System.out.println(Thread.currentThread().getName() + " submitted " + t + ", queue size = " + executor.getQueue().size());
      try {
        executor.execute(t);
      } catch (RejectedExecutionException e) {
        // will be thrown if rejected execution handler
        // is not set with executor.setRejectedExecutionHandler
        e.printStackTrace();
      }
      Thread.sleep(1);
    }
  }
}