javaSE_多线程之线程池

秒速五厘米 2022-05-25 03:24 376阅读 0赞

1) 使用语法

先上一个简单的例子:

public static void useExecutorService(){

ExecutorService executorService = Executors.newFixedThreadPool(3);

for (int i = 0; i < 5; ++i){

executorService.execute(new Runnable(){

@Override

public void run() {

System.out.println(Thread.currentThread().getName());

}

});

}

executorService.shutdown();

}

输出:

pool-1-thread-3

pool-1-thread-2

pool-1-thread-1

pool-1-thread-3

pool-1-thread-2

ExecutorService 用来管理线程池,创建的时候指定了最多有三个线程,每执行一次execute就会启动一个线程,如果已达到3个了,就等待。

调用shutdown后表示启动一个关闭命令,不再接受新任务,线程执行完后自动回收。

2) 线程池对象类型
























线程池对象

说明

newCachedThreadPool

-缓存型池子,先查看池中有没有以前建立的线程,如果有,就reuse.如果没有,就建一个新的线程加入池中

-缓存型池子通常用于执行一些生存期很短的异步型任务

 因此在一些面向连接的daemonSERVER中用得不多。

-reuse的线程,必须是timeout IDLE内的池中线程,缺省timeout60s,超过这个IDLE时长,线程实例将被终止及移出池。

 注意,放入CachedThreadPool的线程不必担心其结束,超过TIMEOUT不活动,其会自动被终止。

newFixedThreadPool

任意时间点,最多只能有固定数目的活动线程存在,此时如果有新的线程要建立,只能放在另外的队列中等待,直到当前的线程中某个线程终止直接被移出池子。

FixedThreadPool多数针对一些很稳定很固定的正规并发线程,多用于服务器。

ScheduledThreadPool

-调度型线程池

-这个池子里的线程可以按schedule依次delay执行,或周期执行

SingleThreadExecutor

-单例线程,任意时间池中只能有一个线程

-用的是和cache池和fixed池相同的底层池,但线程数目是1-1,0IDLE(无IDLE

3) 方法

① isShutdown

boolean isShutdown()
如果此执行程序已关闭,则返回 true。

② isTerminated

boolean isTerminated()
如果关闭后所有任务都已完成,则返回 true。注意,除非首先调用 shutdown 或 shutdownNow,否则 isTerminated 永不为 true。

③ awaitTermination

boolean awaitTermination(long timeout,TimeUnit unit) throws InterruptedException
等待(阻塞)直到关闭或最长等待时间或发生中断
参数:
timeout - 最长等待时间
unit - timeout 参数的时间单位
返回:
如果此执行程序终止,则返回 true;如果终止前超时期满,则返回 false
抛出:
InterruptedException - 如果等待时发生中断

④ Submit

Future submit(Callable task)

  1. 提交一个返回值的任务用于执行,返回一个表示任务的未决结果的 Future

等等。。。。。。篇幅有限,方法略

4) 使用参数

例如说,我有20张票,分四个线程去卖,如何将这些信息传给各线程,并能不重复卖掉。

public static void useExecutorService(){

int threadCount = 4;

int ticket = 20;// 20 张票

int steplength = ticket/threadCount;

ExecutorService executorService = Executors.newFixedThreadPool(threadCount);

System.out.println(“useExecutorService start”);

for (int i = 0; i < threadCount; ++i){

final Integer index_begin = i*steplength + 1;

final Integer index_end = index_begin + steplength - 1;

executorService.execute(new Runnable(){

@Override

public void run() {

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName() + “ : “ + index_begin + “-“ + index_end);

}

});

}

System.out.println(“useExecutorService end”);

executorService.shutdown();

}

定义了四个线程,通过for循环来执行四次线程,这样刚好启动了四个线程。

每个线程在定义的时候就会使用两个变量,每次循环时变量值不一样,这样每个线程都有自己的参数。

输出:

useExecutorService start

useExecutorService end

pool-1-thread-3 : 11-15

pool-1-thread-1 : 1-5

pool-1-thread-2 : 6-10

pool-1-thread-4 : 16-20

可见输出正是我们想要的结果。这里的关键点就在于index_begin,index_end这两个变量,为什么它们能做到可以直接在线程中使用,而且其值就是当时循环时的值呢?就是因为它们被定义为了final。

execute(new Runnable(){

这种语法就叫匿名内部类。

局部内部类和匿名内部类只能访问局部final变量,详见知识点。

5) 判断所有子线程结束

isTerminated

boolean isTerminated()

如果关闭后所有任务都已完成,则返回 true。注意,除非首先调用 shutdown 或 shutdownNow,否则 isTerminated 永不为 true。

返回:

如果关闭后所有任务都已完成,则返回 true

while(true){

  1. **if**(executorService.isTerminated())\{
  2. System.***out***.println("-----------page:" + pageNumber + " run over");
  3. **break**;
  4. \}
  5. Thread.*sleep*(1000);

}

发表评论

表情:
评论列表 (有 0 条评论,376人围观)

还没有评论,来说两句吧...

相关阅读

    相关 java线线

    java多线程之线程池 池化技术 程序的运行,其本质上,是对系统资源(CPU、内存、磁盘、网络等等)的使用。如何高效的使用这些资源是我们编程优化演进的一个方向。今天说

    相关 JavaSE线

    写这篇文章的前提,楼主从学习java开始,自认为技术不错,反正肯费工夫学,为什么我现在又回来准备写一篇关于多线程文章,说真的,现在谁还用多线程?都是封装过的框架,根本不考虑什么

    相关 线线

    前言: 1. 系统启动一个新线程的成本是比较高的,因为它涉及与操作系统交互。在这种情形下,使用线程池可以很好地提高性能,尤其是当程序中需要创建大量生存期很短暂的线程时,