本片文章以Java多线程简单实力为主,全部的例子选自java 编程思想第四版,全部都是自己手动对书 编写,如有疑问请直接留言。

import java.util.ArrayList;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 
 * 
 * 并发编程使我们可以将程序划分为多个分离的、独立运行的任务。通过使用多线程机制,
 * 这些独立任务(也被称为子任务)中的每一个都将由执行线程来驱动。
 * 一个线程就是在进程中的一个单一的顺序控制流,因此,单个进程可以拥有多个并发执行的任务,
 * 但是你的程序使得每个任务都好像有其自己的CPU一样。其底层机制是切分CPU时间,但通常你不需要考虑它。
 * 
 * @create @author Henry @date 2016-11-16 重新查看Java编程思想线程部分。
 */
public class MainThread {
	/**
	 * 
	 * 单独跑run方法,
	 * 
	 * @create @author Henry @date 2016-11-16
	 * 结果如下:
	 * #0(9), #0(8), #0(7), #0(6), #0(5), #0(4), #0(3), #0(2), #0(1),
	 * #0(Liftoff),
	 * @param args
	 */
	public static void main1(String[] args) {
		LiftOff lauch = new LiftOff();
		lauch.run();
	}

	/**
	 * 
	 * 将其付给Thread跑
	 * 
	 * @create @author Henry @date 2016-11-16
	 * 90%结果如下:
	 * Waiting for LiftOff
	 * #0(9), #0(8), #0(7), #0(6), #0(5), #0(4), #0(3), #0(2), #0(1),
	 * #0(Liftoff),
	 * @param args
	 */
	public static void main2(String[] args) {
		Thread thread = new Thread(new LiftOff());
		thread.start();
		System.out.println("Waiting for LiftOff");
	}

	/**
	 * 
	 * 启动5个子线程
	 * 
	 * 输出说明不同任务的执行在线程被换进换出时混在了一起。这种交换是由线程调度器自动控制的。
	 * 如果在你的机器上有多个处理器,线程调度器将会在这些处理器之间默默地分发线程。
	 * 
	 * 当main()创建Thread对象时,它并没有捕获任何对这些对象的引用。在使用普通对象时,
	 * 这对于垃圾回收来说是一场公平的游戏,但是在使用Thread时,情况就不同了。
	 * 每一个Thread都“注册”了它自己,因此确实有一个对它的引用,而且在它的任务退出其run()并死亡之前,
	 * 垃圾回收无法清除它。你可以从输出中看到,这些任务确实运行到了结束,
	 * 因此一个线程会创建一个单独的执行线程,在对start()的调用完成之后,它仍旧会继续存在。
	 * 
	 * @create @author Henry @date 2016-11-16
	 * 结果可能如下:
	 * Waiting for LiftOff
	 * #1(9), #3(9), #0(9), #3(8), #2(9), #3(7), #1(8), #0(8), #2(8),
	 * #0(7),
	 * #4(9), #2(7), #0(6), #2(6), #3(6), #1(7), #4(8), #3(5), #1(6),
	 * #4(7),
	 * #0(5), #2(5), #3(4), #0(4), #1(5), #2(4), #4(6), #0(3), #2(3),
	 * #3(3),
	 * #4(5), #1(4), #0(2), #2(2), #4(4), #0(1), #3(2), #2(1), #1(3),
	 * #4(3),
	 * #0(Liftoff), #2(Liftoff), #3(1), #4(2), #1(2), #3(Liftoff),
	 * #1(1),
	 * #1(Liftoff), #4(1), #4(Liftoff),
	 * @param args
	 */
	public static void main3(String[] args) {
		for (int i = 0; i < 5; i++) {
			new Thread(new LiftOff()).start();
		}
		System.out.println("Waiting for LiftOff");
	}

	/**
	 * 
	 * Java SE5的java.util.concurrent包中的执行器(Executor)将为你管理Thread 对象,
	 * 从而简化了并发编程。Excetor在客户端和任务执行之间提供了一个间接层;
	 * 与客户端直接执行任务不同,这个中介对象将执行任务。Executor允许你管理异步任务的执行,
	 * 而无须显式地管理线程的生命周期。Executor在JavaSE5/6中启动任务的优先方法。
	 * CachedThreadPool在程序执行过程中通常会创建与所需数量相同的线程,
	 * 然后在回收旧线程时停止创建新线程,因此它是合理的Executor的首选。
	 * 只有当这种方式会引发问题是,你才需要切换到FixedTreadPool。
	 * 
	 * @create @author Henry @date 2016-11-16
	 * 
	 * 执行可能结果如下:
	 * #4(9), #2(9), #0(9), #4(8), #0(8), #4(7), #0(7), #4(6), #0(6),
	 * #4(5), #0(5), #4(4), #0(4), #4(3), #0(3), #4(2), #1(9), #4(1),
	 * #4(Liftoff), #3(9), #0(2), #3(8), #1(8), #2(8), #0(1), #3(7),
	 * #0(Liftoff), #2(7), #1(7), #3(6), #2(6), #1(6), #3(5), #2(5),
	 * #1(5), #3(4), #2(4), #1(4), #3(3), #2(3), #1(3), #3(2), #3(1),
	 * #2(2), #2(1), #2(Liftoff), #1(2), #3(Liftoff), #1(1),
	 * #1(Liftoff),
	 * @param args
	 */
	public static void main4(String[] args) {
		ExecutorService exec = Executors.newCachedThreadPool();
		for (int i = 0; i < 5; i++)
			exec.execute(new LiftOff());
		exec.shutdown();
	}

	/**
	 * 
	 * 你可以很容易地将前面实例中的CachedThreadPool替换为不同类型的Executor.
	 * FixedThreadPool使用了有限的线程集来执行所提交的任务;
	 * 有了FixedThreadPool,你就可以一次性预先执行代价高昂的线程分配,
	 * 因而也就可以限制线程的数量了。这可以节省时间,因为你不用为每个任务都固定地付出
	 * 创建线程的开销。在事件驱动的系统中,需要线程的事件处理器,通过直接从池中获取线程,
	 * 也可以如你所愿地尽快得到服务。你不会滥用可获得的资源,因为FixedThreadPool使用的
	 * Thread对象的数量是有界的。
	 * SingleThreadExecutor就是线程数量为1的FixedThreadPool.
	 * 
	 * @create @author Henry @date 2016-11-16
	 * 执行可能结果如下:
	 * #0(9), #3(9), #1(9), #2(9), #4(9), #1(8), #3(8), #1(7), #3(7),
	 * #1(6), #3(6), #1(5), #3(5), #1(4), #3(4), #1(3), #3(3), #1(2),
	 * #3(2), #1(1), #3(1), #4(8), #2(8), #0(8), #1(Liftoff), #2(7),
	 * #4(7), #0(7), #2(6), #3(Liftoff), #0(6), #4(6), #2(5), #0(5),
	 * #0(4), #2(4), #4(5), #0(3), #4(4), #0(2), #2(3), #4(3), #0(1),
	 * #2(2), #4(2), #0(Liftoff), #2(1), #4(1), #2(Liftoff),
	 * #4(Liftoff),
	 * @param args
	 */
	public static void main5(String[] args) {
		ExecutorService exec = Executors.newFixedThreadPool(5);
		for (int i = 0; i < 5; i++)
			exec.execute(new LiftOff());
		exec.shutdown();
	}

	/**
	 * 
	 * 用Future接收返回值:
	 * 
	 * @create @author Henry @date 2016-11-16
	 * 输出结果如下:
	 * result of TaskWithResult 0
	 * result of TaskWithResult 1
	 * result of TaskWithResult 2
	 * result of TaskWithResult 3
	 * result of TaskWithResult 4
	 * result of TaskWithResult 5
	 * result of TaskWithResult 6
	 * result of TaskWithResult 7
	 * result of TaskWithResult 8
	 * result of TaskWithResult 9
	 * 
	 * @param args
	 */
	public static void main6(String[] args) {
		ExecutorService exec = Executors.newCachedThreadPool();
		ArrayList<Future<String>> results = new ArrayList<Future<String>>();
		for (int i = 0; i < 10; i++)
			results.add(exec.submit(new TaskWithResult(i)));
		for (Future<String> fs : results) {
			try {
				System.out.println(fs.isDone());
				System.out.println(fs.get());
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ExecutionException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				exec.shutdown();

			}
		}
	}

	/**
	 * @create @author Henry @date 2016-11-16
	 * 
	 * 运行结果如下:
	 * #0(9), #2(9), #4(9), #1(9), #3(9), #4(8), #2(8), #0(8), #3(8),
	 * #1(8),
	 * #1(7), #0(7), #2(7), #4(7), #3(7), #1(6), #3(6), #0(6), #2(6),
	 * #4(6),
	 * #1(5), #4(5), #3(5), #2(5), #0(5), #3(4), #0(4), #2(4), #4(4),
	 * #1(4),
	 * #2(3), #4(3), #0(3), #3(3), #1(3), #3(2), #2(2), #1(2), #0(2),
	 * #4(2),
	 * #3(1), #4(1), #0(1), #2(1), #1(1), #3(Liftoff), #2(Liftoff),
	 * #1(Liftoff),
	 * #0(Liftoff), #4(Liftoff),
	 * @param args
	 */
	public static void main7(String[] args) {
		ExecutorService exec = Executors.newCachedThreadPool();
		for (int i = 0; i < 5; i++)
			exec.execute(new SleepingTask());
		exec.shutdown();
	}

	/**
	 * 
	 * 测试线程优先级
	 * 
	 * @create @author Henry @date 2016-11-16
	 * 运行结果如下:
	 * Thread[pool-1-thread-6,10,main]:5
	 * Thread[pool-1-thread-3,1,main]:5
	 * Thread[pool-1-thread-1,1,main]:5
	 * Thread[pool-1-thread-5,1,main]:5
	 * Thread[pool-1-thread-6,10,main]:4
	 * Thread[pool-1-thread-2,1,main]:5
	 * Thread[pool-1-thread-4,1,main]:5
	 * Thread[pool-1-thread-6,10,main]:3
	 * Thread[pool-1-thread-3,1,main]:4
	 * Thread[pool-1-thread-1,1,main]:4
	 * Thread[pool-1-thread-5,1,main]:4
	 * Thread[pool-1-thread-6,10,main]:2
	 * Thread[pool-1-thread-2,1,main]:4
	 * Thread[pool-1-thread-4,1,main]:4
	 * Thread[pool-1-thread-6,10,main]:1
	 * Thread[pool-1-thread-2,1,main]:3
	 * Thread[pool-1-thread-4,1,main]:3
	 * Thread[pool-1-thread-3,1,main]:3
	 * Thread[pool-1-thread-1,1,main]:3
	 * Thread[pool-1-thread-5,1,main]:3
	 * Thread[pool-1-thread-2,1,main]:2
	 * Thread[pool-1-thread-4,1,main]:2
	 * Thread[pool-1-thread-3,1,main]:2
	 * Thread[pool-1-thread-4,1,main]:1
	 * Thread[pool-1-thread-2,1,main]:1
	 * Thread[pool-1-thread-1,1,main]:2
	 * Thread[pool-1-thread-5,1,main]:2
	 * Thread[pool-1-thread-3,1,main]:1
	 * Thread[pool-1-thread-1,1,main]:1
	 * Thread[pool-1-thread-5,1,main]:1
	 * 
	 * @param args
	 */
	public static void main8(String[] args) {
		ExecutorService exec = Executors.newCachedThreadPool();
		for (int i = 0; i < 5; i++)
			exec.execute(new SimplePriorities(Thread.MIN_PRIORITY));
		exec.execute(new SimplePriorities(Thread.MAX_PRIORITY));
		exec.shutdown();
	}

	/**
	 * 只要有任何非后台线程还在运行,程序就不会终止。
	 * 比如:main()的就是一个非后台线程
	 * 
	 * @create @author Henry @date 2016-11-16
	 * 运行结果如下:
	 * All daemons started
	 * Thread[Thread-1,5,main] com.think.no21.SimpleDaemons@e09713
	 * Thread[Thread-2,5,main] com.think.no21.SimpleDaemons@19b49e6
	 * Thread[Thread-8,5,main] com.think.no21.SimpleDaemons@47b480
	 * Thread[Thread-4,5,main] com.think.no21.SimpleDaemons@156ee8e
	 * Thread[Thread-0,5,main] com.think.no21.SimpleDaemons@de6f34
	 * Thread[Thread-6,5,main] com.think.no21.SimpleDaemons@83cc67
	 * Thread[Thread-3,5,main] com.think.no21.SimpleDaemons@10d448
	 * Thread[Thread-5,5,main] com.think.no21.SimpleDaemons@e0e1c6
	 * Thread[Thread-7,5,main] com.think.no21.SimpleDaemons@6ca1c
	 * Thread[Thread-9,5,main] com.think.no21.SimpleDaemons@1bf216a
	 * Thread[Thread-2,5,main] com.think.no21.SimpleDaemons@19b49e6
	 * Thread[Thread-8,5,main] com.think.no21.SimpleDaemons@47b480
	 * Thread[Thread-4,5,main] com.think.no21.SimpleDaemons@156ee8e
	 * Thread[Thread-0,5,main] com.think.no21.SimpleDaemons@de6f34
	 * Thread[Thread-6,5,main] com.think.no21.SimpleDaemons@83cc67
	 * 
	 * @param args
	 * @throws Exception
	 */
	public static void main9(String[] args) throws Exception {
		for (int i = 0; i < 10; i++) {
			Thread daemon = new Thread(new SimpleDaemons());
			daemon.setDaemon(true);
			daemon.start();
		}
		System.out.println("All daemons started");
		TimeUnit.MILLISECONDS.sleep(175);
	}

	/**
	 * 通过编写定制的ThreadFactory可以定制由Executor创建线程属性。
	 * 
	 * @create @author Henry @date 2016-11-16
	 * 运行结果如下:
	 * All daemons started
	 * Thread[Thread-1,5,main] com.think.no21.DaemonFromFactory@109a4c
	 * Thread[Thread-3,5,main] com.think.no21.DaemonFromFactory@201f9
	 * Thread[Thread-5,5,main] com.think.no21.DaemonFromFactory@1cf8583
	 * Thread[Thread-2,5,main] com.think.no21.DaemonFromFactory@14693c7
	 * Thread[Thread-4,5,main] com.think.no21.DaemonFromFactory@901887
	 * Thread[Thread-6,5,main] com.think.no21.DaemonFromFactory@665753
	 * Thread[Thread-8,5,main] com.think.no21.DaemonFromFactory@ef22f8
	 * Thread[Thread-9,5,main] com.think.no21.DaemonFromFactory@4a65e0
	 * Thread[Thread-7,5,main] com.think.no21.DaemonFromFactory@3a6727
	 * Thread[Thread-0,5,main] com.think.no21.DaemonFromFactory@1e0cf70
	 * Thread[Thread-1,5,main] com.think.no21.DaemonFromFactory@109a4c
	 * Thread[Thread-3,5,main] com.think.no21.DaemonFromFactory@201f9
	 * Thread[Thread-5,5,main] com.think.no21.DaemonFromFactory@1cf8583
	 * Thread[Thread-7,5,main] com.think.no21.DaemonFromFactory@3a6727
	 * Thread[Thread-9,5,main] com.think.no21.DaemonFromFactory@4a65e0
	 * Thread[Thread-0,5,main] com.think.no21.DaemonFromFactory@1e0cf70
	 * Thread[Thread-6,5,main] com.think.no21.DaemonFromFactory@665753
	 * Thread[Thread-4,5,main] com.think.no21.DaemonFromFactory@901887
	 * Thread[Thread-2,5,main] com.think.no21.DaemonFromFactory@14693c7
	 * Thread[Thread-8,5,main] com.think.no21.DaemonFromFactory@ef22f8
	 * Thread[Thread-9,5,main] com.think.no21.DaemonFromFactory@4a65e0
	 * Thread[Thread-7,5,main] com.think.no21.DaemonFromFactory@3a6727
	 * Thread[Thread-8,5,main] com.think.no21.DaemonFromFactory@ef22f8
	 * Thread[Thread-2,5,main] com.think.no21.DaemonFromFactory@14693c7
	 * Thread[Thread-0,5,main] com.think.no21.DaemonFromFactory@1e0cf70
	 * Thread[Thread-6,5,main] com.think.no21.DaemonFromFactory@665753
	 * Thread[Thread-4,5,main] com.think.no21.DaemonFromFactory@901887
	 * Thread[Thread-5,5,main] com.think.no21.DaemonFromFactory@1cf8583
	 * Thread[Thread-3,5,main] com.think.no21.DaemonFromFactory@201f9
	 * Thread[Thread-1,5,main] com.think.no21.DaemonFromFactory@109a4c
	 * Thread[Thread-9,5,main] com.think.no21.DaemonFromFactory@4a65e0
	 * Thread[Thread-7,5,main] com.think.no21.DaemonFromFactory@3a6727
	 * Thread[Thread-5,5,main] com.think.no21.DaemonFromFactory@1cf8583
	 * Thread[Thread-8,5,main] com.think.no21.DaemonFromFactory@ef22f8
	 * Thread[Thread-2,5,main] com.think.no21.DaemonFromFactory@14693c7
	 * Thread[Thread-0,5,main] com.think.no21.DaemonFromFactory@1e0cf70
	 * Thread[Thread-6,5,main] com.think.no21.DaemonFromFactory@665753
	 * Thread[Thread-4,5,main] com.think.no21.DaemonFromFactory@901887
	 * Thread[Thread-3,5,main] com.think.no21.DaemonFromFactory@201f9
	 * Thread[Thread-1,5,main] com.think.no21.DaemonFromFactory@109a4c
	 * Thread[Thread-5,5,main] com.think.no21.DaemonFromFactory@1cf8583
	 * Thread[Thread-7,5,main] com.think.no21.DaemonFromFactory@3a6727
	 * Thread[Thread-9,5,main] com.think.no21.DaemonFromFactory@4a65e0
	 * Thread[Thread-3,5,main] com.think.no21.DaemonFromFactory@201f9
	 * Thread[Thread-1,5,main] com.think.no21.DaemonFromFactory@109a4c
	 * Thread[Thread-0,5,main] com.think.no21.DaemonFromFactory@1e0cf70
	 * Thread[Thread-2,5,main] com.think.no21.DaemonFromFactory@14693c7
	 * Thread[Thread-8,5,main] com.think.no21.DaemonFromFactory@ef22f8
	 * Thread[Thread-4,5,main] com.think.no21.DaemonFromFactory@901887
	 * Thread[Thread-6,5,main] com.think.no21.DaemonFromFactory@665753
	 * 
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		ExecutorService exec = Executors.newCachedThreadPool(new DaemonThreadFactory());
		for (int i = 0; i < 10; i++)
			exec.execute(new DaemonFromFactory());
		System.out.println("All daemons started");
		TimeUnit.MILLISECONDS.sleep(500);
	}
}

/**
 * 
 * 简单的对象实现Runnable接口
 * 
 * @create @author Henry @date 2016-11-16
 */
class LiftOff implements Runnable {
	protected int countDown = 10;
	private static int taskCount = 0;
	private final int id = taskCount++;

	public LiftOff() {
	}

	public LiftOff(int countDown) {
		this.countDown = countDown;
	}

	public String status() {
		return "#" + id + "(" + (countDown > 0 ? countDown : "Liftoff") + "), ";
	}

	@Override
	public void run() {
		while (countDown-- > 0) {
			System.out.print(status());
			/**
			 * Thread.yield()的调用是对线程调度器(java线程机制的一部分,可以将CPU从一个线程转移给另一个线程)的一种建议,
			 * 它在声明:“我已经执行完生命周期中最重要的部分了,此刻正是切换给其他任务执行一段时间的大好时机。”
			 * 这完全是选择性的,但是这里使用它是因为它会在这些示例中产生更加有趣的输出:你更有可能会看到任务换进换出的证据。
			 * 
			 */
			Thread.yield();
		}
	}
}

/**
 * 
 * 声明带返回值的线程类。
 * 
 * @create @author Henry @date 2016-11-16
 */
class TaskWithResult implements Callable<String> {
	private int id;

	public TaskWithResult(int id) {
		this.id = id;
	}

	@Override
	public String call() throws Exception {
		return "result of TaskWithResult " + id;
	}
}

/**
 * 
 * 影响人物行为的一种简单方法是调用sleep(),这将使任务中止执行给定的时间。
 * 在LiftOff类中,要是把对yield()的调用换成是调用sleep()
 * 
 * @create @author Henry @date 2016-11-16
 */
class SleepingTask extends LiftOff {
	@Override
	public void run() {
		try {
			while (countDown-- > 0) {
				System.out.print(status());
				// Old-style;
				// Thread.sleep(100);
				// java SE5/6-style;
				TimeUnit.MILLISECONDS.sleep(100);
			}
		} catch (InterruptedException e) {
			System.err.println("Interrupted");
		}
	}
}

/**
 * 
 * 测试线程的优先级的类
 * 
 * @create @author Henry @date 2016-11-16
 */
class SimplePriorities implements Runnable {
	private int countDown = 5;
	private volatile double d;// No optimization
	private int priority;

	public SimplePriorities(int priority) {
		this.priority = priority;
	}

	@Override
	public String toString() {
		return Thread.currentThread() + ":" + countDown;
	}

	@Override
	public void run() {
		Thread.currentThread().setPriority(priority);
		while (true) {
			// An expensive,interruptable operation:
			for (int i = 1; i < 100000; i++) {
				d += (Math.PI + Math.E) / (double) i;
				if (i % 1000 == 0)
					Thread.yield();
			}
			System.out.println(this);
			if (--countDown == 0)
				return;
		}
	}
}

/**
 * 后台线程,是指在程序运行的时候再后台提供的一种服务的线程,并且
 * 这种线程不属于程序中不可或缺的部分。因此,当所有的非后台线程结束时,
 * 程序也就终止了,同时会杀死进程中的所有后台线程。
 * 
 * @create @author Henry @date 2016-11-16
 * 
 */
class SimpleDaemons implements Runnable {

	@Override
	public void run() {
		try {
			while (true) {
				TimeUnit.MILLISECONDS.sleep(100);
				System.out.println(Thread.currentThread() + " " + this);
			}
		} catch (InterruptedException e) {
			System.out.println("sleep() interrupted");
		}
	}
}

/**
 * 创建ThreadFactory,将后台状态全部设置为true
 * 
 * @create @author Henry @date 2016-11-16
 * 
 */
class DaemonThreadFactory implements ThreadFactory {

	@Override
	public Thread newThread(Runnable r) {
		Thread t = new Thread(r);
		t.setDaemon(true);
		return t;
	}
}

/**
 * 创建一个新的DeamonFromFactory
 * 
 * @create @author Henry @date 2016-11-16
 * 
 */
class DaemonFromFactory implements Runnable {
	@Override
	public void run() {
		try {
			while (true) {
				TimeUnit.MILLISECONDS.sleep(100);
				System.out.println(Thread.currentThread() + " " + this);
			}
		} catch (InterruptedException e) {
			System.out.println("interrupted");
		}
	}
}
/**
 * 每个静态的ExecutorService创建方法都被重载为接受一个ThreadFactory对象,
 * 而这个对象将被用来创建新的线程:
 * @create @author Henry @date 2016-11-16
 *
 */
class DaemonThreadPoolExecutor extends ThreadPoolExecutor {
	public DaemonThreadPoolExecutor() {
		super(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(),new DaemonThreadFactory());
	}
}




import java.util.concurrent.TimeUnit;
/**
 * 如果是一个后台线程,那么它创建的任何线程江北自动设置成后台线程,
 * 例子如下。
 * @create @author Henry @date 2016-11-18
 *
 */

public class Daemons {
	/**
	 * 运行结果如下:
	 * d.isDaemon = true.
	 * DaemonSpawn 0 started.
	 * DaemonSpawn 1 started.
	 * DaemonSpawn 2 started.
	 * DaemonSpawn 3 started.
	 * DaemonSpawn 4 started.
	 * DaemonSpawn 5 started.
	 * DaemonSpawn 6 started.
	 * DaemonSpawn 7 started.
	 * DaemonSpawn 8 started.
	 * DaemonSpawn 9 started.
	 * t[0].isDaemon()=true
	 * t[1].isDaemon()=true
	 * t[2].isDaemon()=true
	 * t[3].isDaemon()=true
	 * t[4].isDaemon()=true
	 * t[5].isDaemon()=true
	 * t[6].isDaemon()=true
	 * t[7].isDaemon()=true
	 * t[8].isDaemon()=true
	 * t[9].isDaemon()=true
	 *
	 * @param args
	 * @throws InterruptedException
	 */
	public static void main(String[] args) throws InterruptedException {
		Thread d =new Thread(new Daemon());
		d.setDaemon(true);
		d.start();
		System.out.println("d.isDaemon = "+d.isDaemon()+".");
		TimeUnit.SECONDS.sleep(1);
	}
}
/**
 * 在主线程下创建的线程中包含此子线程。
 * @create @author Henry @date 2016-11-18
 *
 */
class Daemon implements Runnable {
	private Thread[] t = new Thread[10];

	@Override
	public void run() {
		for (int i = 0; i < t.length; i++) {
			t[i] = new Thread(new DaemonSpawn());
			t[i].start();
			System.out.println("DaemonSpawn " + i + " started.");
		}
		for (int i = 0; i < t.length; i++)
			System.out.println("t[" + i + "].isDaemon()=" + t[i].isDaemon());
		while (true)
			Thread.yield();
	}
}
/**
 * 
 * 在子线程内再创建的子线程。
 * @create @author Henry @date 2016-11-18
 */
class DaemonSpawn implements Runnable {
	@Override
	public void run() {
		while (true) {
			Thread.yield();
		}
	}
}



import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
 * 你应该意识到后台进程在不执行finally子句的情况下就会终止其run()方法.
 * 此例子说明,当其中一个后台线程结束的时候,其他的后台线程是不能终止的。
 * @create @author Henry @date 2016-11-18
 *
 */
class ADeamon implements Runnable {
	private static int taskCount = 0;
	private final int id = taskCount++;
	@Override
	public void run() {
		try {
			System.out.println(id+" Starting ADaemon");
			if(id!=1){
				TimeUnit.SECONDS.sleep(3);
			}
		} catch (InterruptedException e) {
			System.out.println("Exiting via InterruptedExecption");
		}finally{
			System.out.println(id+" This should always run?");
		}
	}
}
/**
 * 当你运行这个程序时,你将看到finally子句就不会执行,
 * 但是如果你注释掉对setDaemon()的调用,就会看到finally子句将会执行。
 * 
 * @create @author Henry @date 2016-11-18
 *
 */
public class DaemonsDontRunFinally {
	/**
	 * 
	 * @create @author Henry @date 2016-11-18
	 * 运行结果如下:
	 * Starting ADaemon
	 * @param args
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception {
//		for (int i = 0; i < 3; i++) {
//			Thread t=new Thread(new ADeamon());
//			t.setDaemon(true);
//			t.start();
//		}
		ExecutorService exec=Executors.newCachedThreadPool();
		for (int i = 0; i < 3; i++)
			exec.execute(new ADeamon());
		TimeUnit.SECONDS.sleep(2);
		exec.shutdown();
		TimeUnit.SECONDS.sleep(10);
		System.out.println("hello");
	}
}