Java四种线程池

通过线程类构造方法传入CountDownLatch、变量map等参数可收集到线程执行结果
继承Thread或者new一个Thread并传入Runnable的实现 线程测试@Test无效用main执行

ExecutorService的各种线程池策略都是基于ThreadPoolExecutor实现的

Java通过Executors提供四种线程池,分别为:
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

/**
提交一个返回值的任务用于执行,返回一个表示任务的未决结果的 Future。该 Future 的 get 方法在成功完成时将会返回该任务的结果
 */
public class QueryExecutorUtils2 {
	private static final  ExecutorService executor = Executors.newFixedThreadPool(3);//目前和数据库连接数相同
	@Test
	public  void getQueryResult(){
		List resultList = new ArrayList();
		Future[] futures = new Future[10];
		Object obj = new Object();
		try {
			for(int i = 0;i < 10;i++){
					Future<Object> future = executor.submit(new CallableTest());
					futures[i] = future;
			}
			System.out.println("提交完毕");
			//获取所有查询结果
			for(Future future :futures){
				Object result = future.get();//各个线程有未执行完的在这里阻塞
				System.out.println("返回各线程执行结果:"+result);
			}
		} catch (Exception e) {
		}
	}
	static class CallableTest implements Callable<Object> {  
	    @Override  
	    public String call() throws Exception {  
	    	System.out.println("执行 "+Thread.currentThread().getName());
	    	return "result:"+Thread.currentThread().getName();
	    }  
	}
	static class RunableTest implements Runnable {
		@Override
		public void run() {
			System.out.println("执行 "+Thread.currentThread().getName());
		}  
	}
}

 

(1) newCachedThreadPool
创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。对于执行很多短期异步任务的程序而言,这些线程池通常可提高程序性能。调用 execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。因此,长时间保持空闲的线程池不会使用任何资源。注意,可以使用 ThreadPoolExecutor 构造方法创建具有类似属性但细节不同(例如超时参数)的线程池。

package test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolExecutorTest {
public static void main(String[] args) {
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
final int index = i;
try {
Thread.sleep(index * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
cachedThreadPool.execute(new Runnable() {
public void run() {
System.out.println(index);
}
});
}
}
} 

 

初始化corePoolSize个线程,任务量大时,自动新增线程,任务量小时,多于corePoolSize的线程在等待keepAliveTime时间后终止,池中最大线程数为maximumPoolSize

    corePoolSize - 池中所保存的线程数,包括空闲线程。
    maximumPoolSize - 池中允许的最大线程数。
    keepAliveTime - 当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间。
    unit - keepAliveTime 参数的时间单位。
    workQueue - 执行前用于保持任务的队列。此队列仅保持由 execute 方法提交的 Runnable 任务。

java.util.concurrent.ThreadPoolExecutor;
final static int nThreads = 10; final static CountDownLatch endGate = new CountDownLatch(nThreads); public static void main(String[] args) { try { ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(nThreads, nThreads, 1, TimeUnit.MINUTES, new ArrayBlockingQueue<Runnable>(100)); long start = System.currentTimeMillis();//开始时间 for (int i = 0; i < 10; i++) { poolExecutor.execute(new CreateIdThread()); } endGate.await();//使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断。 long end = System.currentTimeMillis();//结束时间 System.out.println("共消耗时间" + (end - start)); } catch (Exception e) { e.printStackTrace(); } } static class CreateIdThread implements Runnable { public void run() { try { Thread.currentThread().sleep(1000); System.out.println("线程:"+Thread.currentThread().getName()); endGate.countDown();//递减锁存器的计数,如果计数到达零,则释放所有等待的线程 } catch (Exception e) { e.printStackTrace(); } } }



(2) newFixedThreadPool
创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。示例代码如下:
Java代码 收藏代码

package test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolExecutorTest {
public static void main(String[] args) {
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
for (int i = 0; i < 10; i++) {
final int index = i;
fixedThreadPool.execute(new Runnable() {
public void run() {
try {
System.out.println(index);
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
}


因为线程池大小为3,每个任务输出index后sleep 2秒,所以每两秒打印3个数字。
定长线程池的大小最好根据系统资源进行设置。如Runtime.getRuntime().availableProcessors()

 

(3) newScheduledThreadPool
创建一个定长线程池,支持定时及周期性任务执行。延迟执行示例代码如下:

@Test
	public void test2() throws Exception {
		ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);

		scheduledThreadPool.schedule(new Runnable() {//无返回结果
			public void run() {
				System.out.println("delay 3 seconds");
			}
		}, 3, TimeUnit.SECONDS);
		
		Future<Object> future = scheduledThreadPool.schedule(new CallableTest(), 3, TimeUnit.SECONDS);
		Object result = future.get();
		System.out.println("返回各线程执行结果:"+result);
	}
	static class CallableTest implements Callable<Object> {  
	    public String call() throws Exception {  
	    	System.out.println("执行 "+Thread.currentThread().getName());
	    	return "result:"+Thread.currentThread().getName();
	    }  
	}

 表示延迟3秒执行。

定期执行示例代码如下:

@Test
	public void test3() throws Exception {
		ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
		scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
			public void run() {
			   System.out.println("delay 1 seconds, and excute every 3 seconds");
			}
		}, 1, 3, TimeUnit.SECONDS);
	}

 表示延迟1秒后每3秒执行一次。不可获取返回结果

 

(4) newSingleThreadExecutor
创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。示例代码如下:
Java代码 收藏代码

package test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolExecutorTest {
public static void main(String[] args) {
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
final int index = i;
singleThreadExecutor.execute(new Runnable() {
public void run() {
try {
System.out.println(index);
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
}


结果依次输出,相当于顺序执行各个任务。

你可以使用JDK自带的监控工具来监控我们创建的线程数量,运行一个不终止的线程,创建指定量的线程,来观察:
工具目录:C:\Program Files\Java\jdk1.6.0_06\bin\jconsole.exe
运行程序做稍微修改:
Java代码 收藏代码

package test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolExecutorTest {
public static void main(String[] args) {
ExecutorService singleThreadExecutor = Executors.newCachedThreadPool();
for (int i = 0; i < 100; i++) {
final int index = i;
singleThreadExecutor.execute(new Runnable() {
public void run() {
try {
while(true) {
System.out.println(index);
Thread.sleep(10 * 1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}


Executors 类提供了使用了 ThreadPoolExecutor 的简单的 ExecutorService 实现,但是 ThreadPoolExecutor 提供的功能远不止于此。我们可以在创建 ThreadPoolExecutor 实例时指定活动线程的数量,我们也可以限制线程池的大小并且创建我们自己的 RejectedExecutionHandler 实现来处理不能适应工作队列的工作

http://blog.csdn.net/defonds/article/details/9715455


ThreadPoolExecutor 继承 AbstractExecutorService 实现了 ExecutorService 继承了 Executor接口
http://825635381.iteye.com/blog/2184680
http://www.importnew.com/19011.html

posted @ 2017-05-27 10:16  苍天一穹  阅读(162)  评论(0)    收藏  举报