您的位置:首页 > 编程语言 > Java开发

(四) Java多线程详解之四种不同线程池使用详解

2017-05-20 17:14 786 查看

线程池

由于线程的生命周期中包括创建、就绪、运行、阻塞、销毁阶段,当我们待处理的任务数目较小时我们可以自己创建几个线程来处理相应的任务,但当有大量的任务时由于创建、销毁线程需要很大的开销,所以引入了线程池的概念

线程池采用预创建的技术,在应用程序启动之后立即创建一定数目的线程放入空闲队列中,这些线程都是处于阻塞(挂起)状态,不消耗CPU只占用较小的内存空间。当任务到来后缓冲池选择一个空闲线程把任务传入此线程中运行,当线程池中的线程都在处理任务线程池自动创建一定数量的新线程用于处理更多的任务。在任务执行完毕后线程也不退出,而是继续保持在线程池中等待下一次的任务,当系统比较空闲时大部分线程都一直处于暂停状态,线程池自动销毁一部分线程回收系统资源

线程池带来的优点

1.避免线程的创建和销毁带来的性能开销
2.避免大量的线程间因互相抢占系统资源导致的阻塞现象
3.能够对线程进行简单的管理并提供定时执行、间隔执行等功能


四种不同线程池

在Java5以前开发者必须手动实现自己的线程池,从Java5开始新增了一个Executors工厂类来产生线程池

newFixedThreadPool 定长线程池

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

public class ThreadExample8 {
public static void main(String[] args) {
ExecutorService threadPool = Executors.newFixedThreadPool(3);
for (int i = 1; i <= 10; i++) {
final int task = i;
threadPool.execute(new Runnable() {
@Override
public void run() {
for (int j = 1; j <= 10; j++) {
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " is looping of " + j + " for  task of " + task);
}
}
});
}
System.out.println("all of 10 tasks have committed!");
}
}


newCachedThreadPool 可缓存线程池

创建一个可缓存线程池,如果线程池长度超过处理需要可灵活回收空闲线程,若无可回收则新建线程。示例代码如下:

public class ThreadExample9 {
public static void main(String[] args) {
ExecutorService threadPool = Executors.newCachedThreadPool();
for (int i = 1; i <= 10; i++) {
final int task = i;
threadPool.execute(new Runnable() {
@Override
public void run() {
for (int j = 1; j <= 10; j++) {
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " is looping of " + j + " for  task of " + task);
}
}
});
}
System.out.println("all of 10 tasks have committed!");
}
}


线程池为无限大,当执行第二个任务时第一个任务已经完成会复用执行第一个任务的线程,而不用每次新建线程

newSingleThreadExecutor 单线程化线程池

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

public class ThreadExample10 {
public static void main(String[] args) {
ExecutorService threadPool = Executors.newSingleThreadExecutor();
for (int i = 1; i <= 10; i++) {
final int task = i;
threadPool.execute(new Runnable() {
@Override
public void run() {
for (int j = 1; j <= 10; j++) {
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " i s looping of " + j + " for  task of " + task);
}
}
});
}
System.out.println("all of 10 tasks have committed!");
}
}


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

newScheduledThreadPool 定时任务线程池

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

public class ThreadExample11 {
public static void main(String[] args) {
Executors.newScheduledThreadPool(3).scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println("定时任务线程池");
}
}, 5, 3, TimeUnit.SECONDS);
}
}


以上线程表示5秒后执行,并且之后每3秒执行一次
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  多线程 线程池