系统启动一个新线程的成本是比较高的,因为它涉及与os交互。这种情况下,系统启动时即创建大量空闲的线程,就可以很好地提高性能,尤其是当程序需要创建大量生存期很短暂的线程时。
除此之外,使用线程池可以有效地控制系统中并发线程的数量。避免因并发创建的线程过多,导致系统性能下降,JVM崩溃。
Java 5以前,需要手动创建自己的线程池;Java 5开始,新增了Executors工厂类产生线程池。
使用线程池执行线程任务的步骤如下:
1.调用Executors 类的静态方法newFixedThreadPool(int nThreads),创建一个可重用的、具有固定线程数的线程池ExecutorService对象
2.创建Runnable实例,作为线程执行任务
3.调用ExecutorService对象的submit()提交Runnable实例
4.调用ExecutorService对象的shutDown()方法关闭线程池。
Executors
ExecutorService newCachedThreadPool()
返回一个带缓存的线程池,该池在必要的时候创建线程,在线程空闲60秒后终止线程。
ExecutorService newFixedThreadPool(int threads)
ExecutorService newSingleThreadExecutor()
ExecutorService
Future submit(Runnable task)
Future submit(Runnable task,T result)
void shutdown()
如下的实例代码,实现了三种开启线程的方式,另外启用了线程池的方式。
@Test
public void test01(){
new MyThread01().start();
new Thread(new MyThread02()).start();
ExecutorService threadPool = Executors.newFixedThreadPool(10);
threadPool.submit( new MyThread03());
}
class MyThread01 extends Thread
{
@Override
public void run()
{
System. out .println("-----MyThread01" );
}
}
class MyThread02 implements Runnable
{
public void run()
{
System. out .println("-----MyThread02" );
}
}
class MyThread03 implements Callable<Integer>
{
@Override
public Integer call() throws Exception
{
System. out .println("-----MyThread03" );
return 200;
}
}
Future类型的对象封装了 异步计算的结果信息。Future对象在第二个submit()方法中,通过调用get方法在方法完成的时候返回result对象。
在使用连接池该做的事儿:
1,调用Executors类中静态的方法newCachedThreadPool或者NewFixedThreadPool
2,调用submint提交Runnable或者Callable对象
3,如果想要取消一个任务,最好保存返回的Future对象
4,当不再提交任务的时候,调用Shutdown()。
预订执行
ScheduleExecutorService接口具有预订执行或重复执行任务而设计的方法。它是一种允许使用线程池机制的java.util.Timer的泛化。
Executors类的newScheduledThreadPool和newSingleThreadScheduleExecutor方法将返回实现了如上接口的对象。
ScheduleFuture