Thread - Thread Execution

线程运行工具也有两种方法实现:

1、Thread

2、ThreadPool

      - Executors.xxx.submit: 运行器  (submit, return Future)

      - ThreadPoolExecutor.execute: 线程池运行器  (execute, void)

主要区别:线程池循环使用线程池中的线程,减少创建和销毁线程。

可以用Future接收运行结果


运行体主要有两种方法实现:

1、Runnable(), run()

2、Callable(), call()

主要区别:Run 没有返回值,Call有返回值。

可以把运行体封装成FutureTask。


一、准备线程

1、Thread

Thread t = new Thread([Runnable | Callable]);

2、Thread Pool Executor

ExecutorService executor = Executors.newFixedThreadPool(n);  // n threads; newSingleThreadExecutor(), newScheduledThreadPool(), ...


二、运行体

1、Run

new Runnable() {
  public void run() {...}
}

2、Call

new Callable<String>() {
  public String call() throws Exception {...; return ...}  // e.g. return String type
}

3、FutureTask

Callable<String> task = ...;  // or Runnable
FutureTask<String> ft = new FutureTask<String>(task);  // e.g.String

三、运行

1、Thread

t.start();

2、Thread Pool Executor

executor.submit([Callable | Runnable])

3、Future

Future<String> future = executor.submit(...)  // similar to thread.start


四、Sample

public class Thread01_future extends Thread {

	public static void main(String[] args) {
		// Future: 异步计算结果

		// Thread.start: 运行器
		// Executors.xxx.submit: 运行器
		// ThreadPoolExecutor.execute: 线程池运行器
		// (execute, void) (submit, return Future)

		// FutureTask: 异步计算任务
		// Runnable(), run(): 运行任务(运行类、运行方法,void)
		// Callable(), call(): 运行任务(运行类、运行方法,return)

		// test01();
		// test02();
		test03();

	}

	// Future: 异步计算结果
	// Executors.xxx.submit: 运行器
	// Runnable(), run(): 运行任务(运行类、运行方法,void)
	// Callable(), call(): 运行任务(运行类、运行方法,return)
	public static void test01() {
		// 创建一个执行任务的服务
		ExecutorService executor = Executors.newFixedThreadPool(3);

		try {
			// 1. A Runnable, however, does not return a result and cannot throw
			// checked exception.
			System.out.println("~~~1");
			Future<?> runnable1 = executor.submit(new Runnable() {
				@Override
				public void run() {
					System.out.println("runnable1 running.");
				}
			});
			System.out.println("Runnable1:" + runnable1.get());

			// 2. Callable
			System.out.println("~~~2");
			Future<String> future1 = executor.submit(new Callable<String>() {
				@Override
				public String call() throws Exception {
					return "result=task1";
				}
			});
			System.out.println("task1: " + future1.get());

			// 3. 对Callable调用cancel可以对对该任务进行中断
			System.out.println("~~~3");
			Future<String> future2 = executor.submit(new Callable<String>() {
				@Override
				public String call() throws Exception {
					try {
						while (true) {
							System.out.println("task2 running.");
							Thread.sleep(50);
						}
					} catch (InterruptedException e) {
						System.out.println("Interrupted task2.");
					}
					return "task2=false";
				}
			});
			// 等待5秒后,再停止第二个任务。因为第二个任务进行的是无限循环
			Thread.sleep(101);
			System.out.println("task2 cancel: " + future2.cancel(true));

			// 4.用Callable时抛出异常则Future什么也取不到了
			// 获取第三个任务的输出,因为执行第三个任务会引起异常
			// 所以下面的语句将引起异常的抛出
			System.out.println("~~~4");
			Future<String> future3 = executor.submit(new Callable<String>() {
				@Override
				public String call() throws Exception {
					throw new Exception("task3 throw exception!");
				}
			});
			// Thread.sleep(133);
			System.out.println("task3: " + future3.get());


		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}

		// 停止任务执行服务
		executor.shutdownNow();
	}

	// FutureTask: 异步计算任务
	// Thread, Executors.xxx.submit: 运行器
	public static void test02() {
		Callable<String> task = new Callable<String>() {
			@Override
			public String call() {
				System.out.println("Sleep start.");
				try {
					Thread.sleep(1000 * 3);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println("Sleep end.");
				return "time=" + System.currentTimeMillis();
			}
		};

		// 直接使用Thread的方式执行
		FutureTask<String> ft = new FutureTask<String>(task);
		Thread t = new Thread(ft);
		t.start();
		try {
			System.out.println("waiting execute result");
			System.out.println("result = " + ft.get());
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}

		// 使用Executors来执行
		System.out.println("=========");
		FutureTask<String> ft2 = new FutureTask<String>(task);
		Executors.newSingleThreadExecutor().submit(ft2);
		try {
			System.out.println("waiting execute result");
			System.out.println("result = " + ft2.get());
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
	}

	// ThreadPoolExecutor.execute: 线程池运行器
	public static void test03() {
		int produceTaskMaxNumber = 4;
		// 构造一个线程池
		ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2, 4, 3,
				TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10),
				new ThreadPoolExecutor.DiscardOldestPolicy());

		ArrayList<FutureTask<String>> tasks = new ArrayList<FutureTask<String>>();
		for (int i = 1; i <= produceTaskMaxNumber; i++) {
			try {
				// 产生一个任务,并将其加入到线程池
				Callable<String> task = new Callable<String>() {
					@Override
					public String call() {
						String task = "task@ ";
						System.out.println("put " + task);
						return task;
					}
				};
				FutureTask<String> futureTask = new FutureTask<String>(
						task);
				threadPool.execute(futureTask);
				tasks.add(futureTask);

			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		for (FutureTask<String> futureTask : tasks) {
			// 1秒内获得结果 (1st arg: the maximum time to wait, 2nd arg: the time
			// unit of the timeout argument)
			String str = null;
			try {
				str = "stop " + futureTask.get(1, TimeUnit.SECONDS);
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (ExecutionException e) {
				e.printStackTrace();
			} catch (TimeoutException e) {
				e.printStackTrace();
			}
			System.out.println(str);
		}
	}
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值