java 线程池

线程池
提供了一个线程队列,队列中保存着所有等待状态的线程。避免了创建与销毁额外开销,提高了响应的速度。

线程池的体系结构

	java.util.concurrent.Executor : 负责线程的使用与调度的根接口
		|--ExecutorService 子接口: 线程池的主要接口
			|--ThreadPoolExecutor 线程池的实现类
			|--ScheduledExecutorService 子接口:负责线程的调度
				|--ScheduledThreadPoolExecutor :继承 ThreadPoolExecutor, 实现 ScheduledExecutorService

Executor
Executor是一个接口,它将任务的提交与任务的执行分离开来,定义了一个接收Runnable对象的方法executor。Executor是Executor框架中最基础的一个接口,类似于集合中的Collection接口。

ExecutorService
ExecutorService继承了Executor,是一个比Executor使用更广泛的子类接口。定义了终止任务、提交任务、跟踪任务返回结果等方法。
一个ExecutorService是可以关闭的,关闭之后它将不能再接收任何任务,对于不在使用的ExecutorService,应该将其关闭以释放资源。

ExecutorService的方法

package java.util.concurrent;
import java.util.List;
import java.util.Collection;
public interface ExecutorService extends Executor {
 /**
 * 平滑地关闭线程池,已经提交到线程池中的任务会继续执行完。
 */
 void shutdown();
 /**
 * 立即关闭线程池,返回还没有开始执行的任务列表。
 * 会尝试中断正在执行的任务(每个线程调用 interruput方法),但这个行为不一定会成功。
 */
 List<Runnable> shutdownNow();
 /**
 * 判断线程池是否已经关闭
 */
 boolean isShutdown();
 /**
 * 判断线程池的任务是否已经执行完毕。
 * 注意此方法调用之前需要先调用shutdown()方法或者shutdownNow()方法,否则总是会返回false
 */
 boolean isTerminated();
 /**
 * 判断线程池的任务是否都执行完。
 * 如果没有任务没有执行完毕则阻塞,直至任务完成或者达到了指定的timeout时间就会返回
 */
 boolean awaitTermination(long timeout, TimeUnit unit)
 throws InterruptedException;
 /**
 * 提交带有一个返回值的任务到线程池中去执行(回调),返回的 Future 表示任务的待定结果。
 * 当任务成功完成后,通过 Future 实例的 get() 方法可以获取该任务的结果。
 * Future 的 get() 方法是会阻塞的。
 */
 <T> Future<T> submit(Callable<T> task);
 /**
 *提交一个Runnable的任务,当任务完成后,可以通过Future.get()获取的是提交时传递的参数T result
 * 
 */
 <T> Future<T> submit(Runnable task, T result);
 /**
 * 提交一个Runnable的人无语,它的Future.get()得不到任何内容,它返回值总是Null。
 * 为什么有这个方法?为什么不直接设计成void submit(Runnable task)这种方式?
 * 这是因为Future除了get这种获取任务信息外,还可以控制任务,
 具体体现在 Future的这个方法上:boolean cancel(boolean mayInterruptIfRunning)
 这个方法能够去取消提交的Rannable任务。
 */
 Future<?> submit(Runnable task);
 /**
 * 执行一组给定的Callable任务,返回对应的Future列表。列表中每一个Future都将持有该任务的结果和状态。
 * 当所有任务执行完毕后,方法返回,此时并且每一个Future的isDone()方法都是true。
 * 完成的任务可能是正常结束,也可以是异常结束
 * 如果当任务执行过程中,tasks集合被修改了,那么方法的返回结果将是不确定的,
 即不能确定执行的是修改前的任务,还是修改后的任务
 */
 <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
 throws InterruptedException;
 /**
 * 执行一组给定的Callable任务,返回对应的Future列表。列表中每一个Future都将持有该任务的结果和状态。
 * 当所有任务执行完毕后或者超时后,方法将返回,此时并且每一个Future的isDone()方法都是true。
 * 一旦方法返回,未执行完成的任务被取消,而完成的任务可能正常结束或者异常结束, 
 * 完成的任务可以是正常结束,也可以是异常结束
 * 如果当任务执行过程中,tasks集合被修改了,那么方法的返回结果将是不确定的
 */
 <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
 long timeout, TimeUnit unit)
 throws InterruptedException;
 /**
 * 执行一组给定的Callable任务,当成功执行完(没抛异常)一个任务后此方法便返回,返回的是该任务的结果
 * 一旦此正常返回或者异常结束,未执行的任务都会被取消。 
 * 如果当任务执行过程中,tasks集合被修改了,那么方法的返回结果将是不确定的
 */
 <T> T invokeAny(Collection<? extends Callable<T>> tasks)
 throws InterruptedException, ExecutionException;
 /**
 * 执行一组给定的Callable任务,当在timeout(超时)之前成功执行完(没抛异常)一个任务后此方法便返回,返回的是该任务的结果
 * 一旦此正常返回或者异常结束,未执行的任务都会被取消。 
 * 如果当任务执行过程中,tasks集合被修改了,那么方法的返回结果将是不确定的
 */
 <T> T invokeAny(Collection<? extends Callable<T>> tasks,
 long timeout, TimeUnit unit)
 throws InterruptedException, ExecutionException, TimeoutException;
}

线程池工具类 Executors :

ExecutorService newFixedThreadPool() : 创建固定大小的线程池
ExecutorService newCachedThreadPool() : 缓存线程池,线程池的数量不固定,可以根据需求自动的更改数量。
ExecutorService newSingleThreadExecutor() : 创建单个线程池。线程池中只有一个线程

ScheduledExecutorService newScheduledThreadPool() : 创建固定大小的线程,可以延迟或定时的执行任务。

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.*;


public class ThreadPoolDemo {

    public static void main(String[] args) throws Exception {
        fixedThreadPoolExecRunnableTask();
        // fixedThreadPoolExecCallableTask();
        // scheduledThreadPoolExecCallableTask();
    }

    // 创建固定大小的线程池, 执行 实现 Callable 接口 的线程任务, 可以延迟或定时的执行任务。
    public static void scheduledThreadPoolExecCallableTask()  throws Exception {
        //1. 创建线程池 固定数量5个, 可以延迟或定时的执行任务。
        ScheduledExecutorService pool = Executors.newScheduledThreadPool(5);

        //2. 为线程池中的线程分配任务
        for (int i = 0; i < 5; i++) {
        	// schedule(Callable<T> task)方法
            Future<Integer> result = pool.schedule(new Callable<Integer>(){

                @Override
                public Integer call() throws Exception {
                    int num = new Random().nextInt(100);//生成随机数
                    System.out.println(Thread.currentThread().getName() + " : " + num);
                    return num;
                }

            }, 1, TimeUnit.SECONDS);

            System.out.println(result.get());
        }

        //3. 关闭线程池
        pool.shutdown();
    }

    
    // 创建固定大小的线程池, 执行 实现 Callable 接口 的线程任务
    public static void fixedThreadPoolExecCallableTask() throws Exception {
        //1. 创建线程池 固定数量5个
        ExecutorService pool = Executors.newFixedThreadPool(5);

        // 保存 线程任务 返回 的 Future 对象
        List<Future<Integer>> list = new ArrayList<>();

        //2. 为线程池中的线程分配任务
        for (int i = 0; i < 10; i++) {
        	// submit(Callable<T> task)方法
            Future<Integer> future = pool.submit(new Callable<Integer>() { // Callable

                @Override
                public Integer call() throws Exception {
                    int sum = 0;

                    for (int i = 0; i <= 100; i++) {
                        sum += i;
                    }

                    return sum;
                }

            });

            list.add(future);
        }

        //3. 关闭线程池
        pool.shutdown();

        // 遍历 线程任务 返回 的 Future 对象
        for (Future<Integer> future : list) {
            System.out.println(future.get());
        }
    }
    

    // 创建固定大小的线程池, 执行 实现 Runnable 接口 的线程任务
    public static void fixedThreadPoolExecRunnableTask() {
        //1. 创建线程池 固定数量5个
        ExecutorService pool = Executors.newFixedThreadPool(5);

        //2. 为线程池中的线程分配任务
        for (int i = 0; i < 10; i++) {
            pool.submit(new Runnable() { // Runnable
                private int i = 0;

                @Override
                public void run() {
                    while(i <= 100){
                        System.out.println(Thread.currentThread().getName() + " : " + i++);
                    }
                }
            });
        }

        //3. 关闭线程池
        pool.shutdown();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java线程池是一种用于管理和复用线程的机制,它可以提高多线程应用程序的性能和效率。线程池的线程可以被重复使用,避免了频繁创建和销毁线程的开销。 在Java线程池可以通过`ExecutorService`接口来创建和管理。线程池的线程可以执行提交给它的任务,并且可以根据需要自动创建新的线程或销毁闲置的线程。 嵌套线程池是指在一个线程池创建另一个线程池。这种情况通常发生在需要处理一些复杂的任务,其每个任务本身也需要使用线程池来执行。 下面是一个示例代码,演示了如何在Java嵌套使用线程池: ```java import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class NestedThreadPoolExample { public static void main(String[] args) { // 创建外层线程池 ExecutorService outerThreadPool = Executors.newFixedThreadPool(5); // 提交任务给外层线程池 outerThreadPool.execute(() -> { // 创建内层线程池 ExecutorService innerThreadPool = Executors.newFixedThreadPool(3); // 提交任务给内层线程池 innerThreadPool.execute(() -> { // 内层线程池执行的任务 System.out.println("Inner thread pool task executed"); }); // 关闭内层线程池 innerThreadPool.shutdown(); }); // 关闭外层线程池 outerThreadPool.shutdown(); } } ``` 在上面的示例,我们首先创建了一个外层线程池`outerThreadPool`,它使用`Executors.newFixedThreadPool()`方法创建了一个固定大小的线程池。然后,我们向外层线程池提交了一个任务,该任务在执行时创建了一个内层线程池`innerThreadPool`,并向内层线程池提交了一个任务。最后,我们分别关闭了内层线程池和外层线程池

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值