线程,线程池,总结

总结一下个人对线程,线程池的理解(持续更新)

一、线程的3种实现方式

Thread

Runnable

Callable

3种代码实现都很简单,不详聊了(多说一句:callable 可以通过2种方式调用 1 FutureTask 2 线程池时用Future)

总结一下:

Thread的缺陷 new一次就创建一个真实线程
而runnable和callable不一定会创建,可能会线程池里面找到已有的线程去执行所需要的

而runnable和callable的区别在于是否有返回值

二、线程池创建

4种线程池的创建方式

FixedThreadPool  定长线程池(最常用)

CachedThreadPool 可缓存线程池

SingleThreadPool 单个线程池

ScheduledThreadPool 处理周期问题线程池

关于ScheduledThreadPool 线程池,可看我另一篇文章 https://mp.csdn.net/postedit/80309526

三、线程池类型

ExecutorService 和 CompletionService 区别

ExecutorService 非阻塞

CompletionService 阻塞

public class DoubleTypeThreadPool {
	
	final static ExecutorService es = Executors.newFixedThreadPool(4);
	
	final static CompletionService es1 = new ExecutorCompletionService(es);
	
	public static void main(String[] args) {

		List<Future<Object>> listFuture2 = new ArrayList<Future<Object>>();
		// listFuture2.add(es.submit(new BatchThread1()));
		// listFuture2.add(es.submit(new BatchThread2()));

		CountDownLatch countDownLatch = new CountDownLatch(2);
		try {
			List<Callable<Object>> tasks = new ArrayList<>();
			tasks.add(new BatchThread1());
			tasks.add(new BatchThread2());
			try {
				listFuture2 = es.invokeAll(tasks);
				for (Future<Object> o : listFuture2) {
					try {
						System.out.println("ExecuteService " + o.get());
					} catch (InterruptedException e) {
						e.printStackTrace();
					} catch (ExecutionException e) {
						e.printStackTrace();
					}
				}
			} catch (InterruptedException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		} catch (Exception e) {
		} finally {
			countDownLatch.countDown();
		}
		try {
			countDownLatch.await();
		} catch (InterruptedException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

//		List<Future<Object>> listFuture = new ArrayList<Future<Object>>();
//
//		listFuture.add(es1.submit(new BatchThread1()));
//		listFuture.add(es1.submit(new BatchThread2()));
//
//		// tasks1.add(new BatchThread1()) ;
//		// tasks1.add(new BatchThread2()) ;
//		for (Future<Object> o1 : listFuture) {
//			try {
//				System.out.println("CompletionService " + o1.get());
//			} catch (InterruptedException e) {
//				e.printStackTrace();
//			} catch (ExecutionException e) {
//				e.printStackTrace();
//			}
//		}
	}

}
class BatchThread1<Object> implements Callable<Object> {

	/**
	 * (非 Javadoc)
	 *
	 *
	 * @return
	 * @throws Exception
	 * @see java.util.concurrent.Callable#call()
	 */
	@Override
	public Object call() throws Exception {
		Thread.sleep(2000);
		System.out.println("BatchThread1");
		return (Object) Collections.EMPTY_LIST;
	}
}

class BatchThread2<Object> implements Callable<Object> {

	/**
	 * (非 Javadoc)
	 *
	 *
	 * @return
	 * @throws Exception
	 * @see java.util.concurrent.Callable#call()
	 */
	@Override
	public Object call() throws Exception {
		Thread.sleep(5000);
		System.out.println("BatchThread2");
		return (Object) Collections.EMPTY_LIST;
	}
}

四 、关于线程池关闭

shutdown 使线程池到wait状态 ,清空里面的线程

shutdownNow 使线程池到stop状态,声明周期结束

引用大神的一段话:
执行时间和内存空间是一对永恒的矛盾, 包括线程池在内的很多“池化”思想,都是用内存空间换取执行时间。所以,内存肯定是占用了,但相比当需要线程时去创建,用完后再销毁,所耗费的资源,占用些内存是更合理的。所以才会选择用线程池来维护一些不销毁的线程。

最后,推荐一本好书,《JAVA并发编程实战》 密码 fcbi

猜你喜欢

转载自blog.csdn.net/pengjj1223/article/details/80523314