java 并发库之 Executors

本篇简单介绍java并发库的Executors概念。

new Thread弊端


new Thread(new Runnable() {
 
	@Override
	public void run() {
		// TODO Auto-generated method stub
	}
}).start();

new Thread 的弊端如下:

  • a. 每次new Thread新建对象性能差
  • b. 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源导致死机或oom
  • c. 缺乏更多功能,如定时执行、定期执行、线程中断

相比new ThreadJava提供的四种线程池的好处在于:

  • a. 重用存在的线程,减少对象创建、消亡的开销,性能佳。
  • b. 可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞。
  • c. 提供定时执行、定期执行、单线程、并发数控制等功能。

Executors

Executors 线程池

  • newFixedThreadPool:返回一个包含指定数目线程的线程池,如果任务数量多于线程数目,那么没有没有执行的任务必须等待,直到有任务完成为止。

  • newSingleThreadExecutor:返回以个包含单线程的Executor,将多个任务交给此Exector时,这个线程处理完一个任务后接着处理下一个任务,若该线程出现异常,将会有一个新的线程来替代。

  • newCachedThreadPool:根据用户的任务数创建相应的线程来处理,该线程池不会对线程数目加以限制,完全依赖于JVM能创建线程的数量,可能引起内存不足。


package concurrent;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class MyExecutor extends Thread {
	private int index;
	public MyExecutor(int i) {
		this.index = i;
	}
	public void run() {
		try {
			System.out.println("[" + this.index + "] start....");
			Thread.sleep((int) (Math.random() * 1000));
			System.out.println("[" + this.index + "] end.");
		}catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void main(String args[]) {
		//接口 Java.util.concurrent.ExecutorService 表述了异步执行的机制,并且可以让任务在后台执行。
		/*
		 * execute(Runnable):接收一个runnable 并且异步执行
		 * submit(Runnable) :接收一个runnable ,返回Future 对象。这個 Future 对象可以用于判断 Runnable 是否结束执行
		 *                    Future future.get() 返回null 表示任务结束 
		 * 
		 */

		ExecutorService service1 = Executors.newFixedThreadPool(4);
		ExecutorService service2 = Executors.newSingleThreadExecutor();  
		ExecutorService service3 = Executors.newCachedThreadPool();  
		for (int i = 0; i < 10; i++) {
			service3.execute(new MyExecutor(i));
		}
		System.out.println("submit finish");
		service3.shutdown();
	}

}


从左到右,依次为 newFixedThreadPool,newSingleThreadExecutor,newCachedThreadPool

outPut

Future

上一节Executors中,接口 Java.util.concurrent.ExecutorService中的submit(Runnable)就会返回一个Future对象。

Future 表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。

计算完成之后只能通过,Future future.get() 来获取结果。

Update 2017/10/24

阿里编码规范 告诉我们


ExecutorService service2 = Executors.newSingleThreadExecutor();  

outPut

所以要改成ThreadPoolExecutor 线程池这种形式。


//如

ExecutorService service2 = Executors.newSingleThreadExecutor();  

//改为

ExecutorService service2 = new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>()));  

//或是

ThreadFactory factory = new ThreadFactoryBuilder().setNameFormat("thread-pool-%d").build();
ExecutorService service2 = new ThreadPoolExecutor(1,1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingDeque<Runnable>(),factory);

posted @ 2018-09-17 15:07  可爱的黑精灵  阅读(251)  评论(0编辑  收藏  举报