Java线程的四种创建方式

Java线程的四种创建方式:

1 使用Thread子类创建和启动线程

2 使用实现Runnable的实现类创建和启动线程

3 使用Callable和FutureTask来创建异步任务,然后创建线程实例

4 通过线程池创建线程(JUC)

(1)向线程池提交任务的两种方式:

方式一:使用execute方法(无返回值)

void execute(Runnable command);

方式二:使用submit方法(有返回值、可简单管理线程,并且可以处理异常)

    Future<?> submit(Runnable task);

    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException;

(2)关闭线程池:

pool.shutdown();

4.1 Executors四个快捷创建线程池方法(不推荐)

4.1.1 newSingleThreadExecutor()创建单一线程池

(1)任务按照次序执行
(2)池中只有唯一线程,并且存活时间是无限的
(3)线程繁忙时,新任务会进入到阻塞队列

场景:任务依次执行。

4.1.2 newFixedThreadPool(3)创建固定数量线程池

场景:处理CPU密集型的任务。在CPU被工作线程长时间使用的情况下,能确保尽可能少的分配线程。

弊端:内部使用无界队列来存放任务,当任务超过线程池最大容量需要处理时,队列无限增大,使服务器资源耗尽。

4.1.3 newCachedThreadPool()可缓存线程池

场景:快速处理突发性强、耗时较短的任务。

弊端:没有最大线程池数量限制。

4.1.4 newScheduledThreadPool(2)可调度线程池

    // 内含一个线程池
    newSingleThreadScheduledThreadPool();
    // 内含n个线程池
    newScheduledThreadPool(int corePoolSize);

通过scheduleAtFixedRate方法提交任务:

    ScheduledFuture<?> scheduleAtFixedRate(
        Runnable command,
        // 首次执行任务延迟时间
        long initialDelay,
        // 执行任务间隔时间
        long period,
        // 计时单位
        TimeUnit unit);

场景:周期性执行任务场景。

4.2 创建标准线程池的方法(推荐)

快捷创建线程池的方法存在严重的性能问题,所以大部分企业都禁止使用快捷线程池,要求通过标准构造器ThreadPoolExecutor构造线程池。

    // 标准构造器
    public ThreadPoolExecutor(
        // 核心线程数,即使线程空闲(idle),也不会回收
        int corePoolSize,
        // 线程数上限
        int maximumPoolSize,
        // 线程最大空闲(idle)时长
        long keepAliveTime, TimeUnit unit,
        // 任务的排队队列
        BlockingQueue<Runnable> workQueue,
        // 新线程的产生方式
        ThreadFactory threadFactory,
        // 拒绝策略
        RejectedExecutionHandler handler)
posted @ 2022-01-12 22:27  百成  阅读(1254)  评论(0编辑  收藏  举报