前言
在 Java多线程入门(一)——在屏幕上交替打印数字、字母中我们已经会创建任务类并将其放入线程中执行。
这种方法对一单一的任务是非常方便的,但是必须为每一个任务创建一个线程,因此对于大量任务来说,这种方式并不好。
为每一个任务都创建一个新线程可能会限制流量并且造成性能降低。
线程池
线程池是管理并发执行任务个数的理想方式。在线程池中,如果一个线程完成了任务,它可以被重新使用并且用以执行另一个任务。
如果线程池中的所有线程都不是处以空闲状态,而且还有其他任务在等待执行,那么系统会重新创建一个新的线程去代替它。如果此时有一个线程因为某些原因中断了,那么系统会重新创建一个新的线程去代替它。
如果缓冲池中的线程在60秒内都没有被使用,那么这些线程会终止。
线程池的使用
package P1;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static java.lang.Thread.sleep;
public class thread1 {
public static void main(String[] args){
//创建一个最大容量为3的线程池
ExecutorService executor= Executors.newFixedThreadPool(3);
//提交任务给线程池
executor.execute(new PrintChar('a',100));
executor.execute(new PrintChar('b',100));
executor.execute(new PrintNum(100));
//关闭线程池
executor.shutdown();
}
}
class PrintChar implements Runnable{
private char charToPrint;//需要打印的字母
private int times;//需要打印的次数
public PrintChar() {
}
public PrintChar(char charToPrint, int times) {
this.charToPrint = charToPrint;
this.times = times;
}
@Override
public void run() {
for (int i = 0; i <= times; i++) {
System.out.println(charToPrint);
}
}
}
class PrintNum implements Runnable{
private int lastNum;
public PrintNum(int lastNum) {
this.lastNum = lastNum;
}
@Override
public void run() {
for (int i = 1; i < lastNum; i++) {
System.out.println(" " + i);
}
}
思路
我们在上述程序中创建了一个最大线程数为3的线程池执行器,我们把创建好的任务添加进入线程池。执行器会创建3个线程并发执行三个任务
如果将线程池的创建代码改为
ExecutorService executor= Executors.newCachedThreadPool();
那么线程池会为每一个等待的任务都创建一个新线程,让所有的任务都并发执行。
在所有任务都执行完毕之后,线程池会关闭。