如果把ExecutorService对象的引用弄丢了会如何样

如果把ExecutorService对象的引用弄丢了会怎么样?
以下是一段测试代码:
package test;
import java.util.*;
import java.math.*;
import java.util.concurrent.locks.*;
import java.util.concurrent.*;
public class Test3  {
	
	static class Task1 implements Runnable{
		public void  run(){
			System.out.println("Task1!");
			try{
				TimeUnit.SECONDS.sleep(1);
			}catch(InterruptedException e){}
			for (int i=0;i<10;i++){
				System.out.println("Task1!"+" "+i);
				if (i%3==0) Thread.yield();
			}
			
		}
	}
	static class Task2 implements Runnable {
		
		public void run(){
			System.out.println("Task2!");
			try{
				TimeUnit.SECONDS.sleep(1);
			}catch(InterruptedException e){}
			for (int i=0;i<10;i++){
				System.out.println("Task2!"+" "+i);
				if (i%3==0) Thread.yield();
			}
		}
	}
	static class Task3 implements Runnable {
		public void run(){
			System.out.println("Task3!");
			try{
				TimeUnit.SECONDS.sleep(1);
			}catch(InterruptedException e){}
			for (int i=0;i<10;i++){
				System.out.println("Task3!"+" "+i);
				if (i%3==0) Thread.yield();
			}
		}
	}
	public static void main(String[] args){
		ExecutorService exec=Executors.newFixedThreadPool(2);
		exec.execute(new Task1());
		exec.execute(new Task2());
		//第三个任务需要在队列中等待
		exec.execute(new Task3());
		exec=null;
		//不执行shutdown的话这个程序就不会停止,这是与直接使用 Thread不同之处,
		//Thread一旦任务完成自动进入TERMINATED,而线程池中的线程不会,它只是处于WAITING中
//		exec.shutdown();
                  System.gc();
		System.out.print("The end of main()!\n");
                 
	}
}



输出结果就是:
Task1!
Task2!
The end of main()!
Task2! 0
Task2! 1
Task2! 2
Task2! 3
Task2! 4
Task2! 5
Task2! 6
Task2! 7
Task2! 8
Task2! 9
Task3!
Task1! 0
Task1! 1
Task1! 2
Task1! 3
Task1! 4
Task1! 5
Task1! 6
Task1! 7
Task1! 8
Task1! 9
Task3! 0
Task3! 1
Task3! 2
Task3! 3
Task3! 4
Task3! 5
Task3! 6
Task3! 7
Task3! 8
Task3! 9

首先,很显然的是,在Task1和Task2结束之前,exec已经为null,也就是ExecutorService对象丢失了。并且我们强制垃圾回收了。然而,所有的任务都正确执行完成了。换句话说,这也就意味着虽然我们丢失了对exec原来对象的引用(按照正常的理解,那应该会被回收掉的才对)但是ExecutorService对象仍然存活着,并且这个程序不会终止(因为我们没有调用shutdown方法)。事实证明,即使ExecutorService对象变成了“垃圾”也不会被回收,这与Thread对象一样,它们自己在JVM注册了“身份”,在运行完成前不会被当做垃圾回收。这也提醒了我们,要在正确时机关闭线程池,不然这个程序就不会自行结束了(当然对于CachedThreadPool而言,因为它的线程超时是1分钟,如果1分钟过后没有任务的话就会自行终止,当所有线程终止了,那池也关闭了)