系统启动一个新线程的成本是比较高的,因为它涉及与操作系统交互。在这种情形下,使用线程池可以很好地提高性能,尤其是当程序中需要创建大量生存周期很短的线程时,更应该考虑使用线程池。
使用线程池可以有效地控制系统中并发线程的数量,当系统中包含大量并发线程时,会导致系统性能剧烈下降,甚至导致JVM崩溃,而线程池的最大线程数参数可以控制系统中并发线程数不超过此数。
从JAVA5开始新增了一个Executors工具类来产生线程池,它有如下几个静态工厂方法来创建线程池。
强烈建议程序员使用较为方便的 Executors 工厂方法 Executors.newCachedThreadPool()(无界线程池,可以进行自动线程回收)、
Executors.newFixedThreadPool(int)(固定大小线程池)
Executors.newSingleThreadExecutor()(单个后台线程)
Executors.newScheduledThreadPool(int corePoolSize) 可以指定延迟后执行线程任务。
ExecutorService代表尽快执行线程的线程池(只要线程池中有空闲的线程,就立即执行线程任务),程序只要将一个Runnable对象或Callable对象(代表线程任务)提交给该线程,该线程就会尽快执行该任务
当用完一个线程池后,应该嗲用该线程池的shutdown()方法,该方法将启动线程池的关闭序列,调用shutdown()方法后的线程池不再接受新任务,但将以前所有已提交任务执行完。当线程池中的所有任务都执行完成后,池中的所有线程都会死亡;另外也可以调用线程池中的shutdownNow()方法来关闭线程池,该方法试图停止所有正在执行的活动任务,暂停处理正在等待的任务,并返回等待执行任务列表。
package hb.threadpool;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class FixedThreadPoolDemo {
public static void main(String[] args) {
ExecutorService es = Executors.newFixedThreadPool(2);
// ExecutorService es = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
final int count = i;
//过两秒启动线程运行里面的run方法
es.submit(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "----------" + count);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
System.out.println(es.isShutdown());
//等待线程运行完毕之后再停止线程。
es.shutdown();
//强制停止线程,如果当前线程正在执行,则被强制停止。
// es.shutdownNow();
System.out.println(es.isShutdown());
}
}
package hb.threadpool;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ScheduledThreadPoolExecutorDemo {
public static void main(String[] args) {
// ScheduledThreadPoolExecutor stpe = new ScheduledThreadPoolExecutor(2);
ScheduledExecutorService stpe = Executors.newScheduledThreadPool(2);;
for (int i = 0; i < 10; i++) {
final int count = i;
//过两秒启动线程运行里面的run方法
stpe.schedule(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "----------" + count);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, 2, TimeUnit.SECONDS);
}
System.out.println(stpe.isShutdown());
//等待线程运行完毕之后再停止线程。
stpe.shutdown();
//强制停止线程,如果当前线程正在执行,则被强制停止。
// stpe.shutdownNow();
System.out.println(stpe.isShutdown());
}
}