线程池入门--二(Executors获取ExecutorService静态方法)

Executor的三个静态方法

这里所有线程都用ThreadFactory创建,这样的线程无需手动启动,自动执行

newCachedThreadPool

package com.cy.thead;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

/**
 * 练习Executors获取ExecutorService,然后调用方法,提交任务;
 * newCachedThreadPool
 * 创建一个默认的线程池对象,里面的线程可重用,且在第一次使用时才创建
 * 数量不做限制,每一次有任务来的时候都是以任务优先,性能最大化(要求服务器硬件跟得上,因为服务器压力比较大)
 */
public class MyTest01_newCachedThreadPool {
    public static void main(String[] args) {
        //test01();
        test02();
    }
    //练习newCachedThreadPool方法
    private static void test01() {
        //使用工厂类获取线程池对象(newCachedThreadPool的线程空闲60s会自动销毁)默认工厂创建工厂
        ExecutorService es = Executors.newCachedThreadPool();
        //提交任务
        for (int i=1;i<10;i++){
            es.submit(new MyRunnale(i));
        }
    }
    private static void test02() {
        //使用工厂类获取线程池对象(newCachedThreadPool的线程空闲60s会自动销毁)自己指定的工厂创建线程

        ExecutorService es = Executors.newCachedThreadPool(new ThreadFactory() {
            int n=1;
            @Override
            public Thread newThread(Runnable r) {

                return new Thread(r,"自定义的线程名称"+n++);
            }
        });
        //提交任务
        for (int i=1;i<10;i++){
            es.submit(new MyRunnale(i));

        }
    }
}

/**
 * 任务类,包含一个任务编号,在任务中打印出是哪一个线程执行了任务
 */
class MyRunnale implements Runnable{
    private int id;
    public MyRunnale(int id) {
        this.id = id;
    }
    @Override
    public void run() {
        //获取线程的名称,打印一句话
        String name = Thread.currentThread().getName();
        System.out.println(name+"执行了任务..."+id);
    }
}

newFixedThreadPool

package com.cy.thead;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

/**
 * 练习Executors获取ExecutorService,然后调用方法,提交任务;
 * newFixedThreadPool
 * 创建一个可重用的固定线程数的线程池
 * 压力比较低,可以规定线程数量
 */
public class MyTest02_newFixedThreadPool {
    public static void main(String[] args) {
        //test01();
        test02();
    }
    //练习newFixedThreadPool方法
    private static void test01() {
        //使用工厂类获取线程池对象(new3个线程)
        ExecutorService es = Executors.newFixedThreadPool(3);
        //提交任务
        for (int i=1;i<10;i++){
            es.submit(new MyRunnale2(i));

        }
    }
    private static void test02() {
        //使用工厂类获取线程池对象(newFixedThreadPool创建3个线程,并且都是由我们自己(ThreadFactory)参与创建的线程)
        ExecutorService es = Executors.newFixedThreadPool(3,new ThreadFactory() {
            int n=1;
            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r,"自定义的线程名称"+n++);
            }
        });
        //提交任务
        for (int i=1;i<10;i++){
            es.submit(new MyRunnale2(i));

        }
    }
}

/**
 * 任务类,包含一个任务编号,在任务中打印出是哪一个线程执行了任务
 */
class MyRunnale2 implements Runnable{
    private int id;

    public MyRunnale2(int id) {
        this.id = id;
    }

    @Override
    public void run() {
        //获取线程的名称,打印一句话
        String name = Thread.currentThread().getName();
        System.out.println(name+"执行了任务..."+id);
    }
}

newSingleThreadExecutor

package com.cy.thead;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

/**
 * 练习Executors获取ExecutorService,然后调用方法,提交任务;
 * newSingleThreadExecutor
 * 创建一个使用单个worker线程的Executor,以无界队列方式来运行该线程
 * 只追求安全不考虑性能可以用这个单线程
 */
public class MyTest03_newSingleThreadExecutor {
    public static void main(String[] args) {
//        test01();
        test02();
    }
    //newSingleThreadExecutor方法只有一个线程
    private static void test01() {
        //使用工厂类获取线程池对象(newSingleThreadExecutor方法)
        ExecutorService es = Executors.newSingleThreadExecutor();
        //提交任务
        for (int i=1;i<10;i++){//创建九个线程测试
            es.submit(new MyRunnale3(i));
        }
    }
    private static void test02() {
        //使用工厂类获取线程池对象(newSingleThreadExecutor)
        ExecutorService es = Executors.newSingleThreadExecutor(new ThreadFactory() {
            int n=1;
            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r,"自定义的线程名称"+n++);
            }
        });
        //提交任务
        for (int i=1;i<10;i++){
            es.submit(new MyRunnale3(i));

        }
    }
}

/**
 * 任务类,包含一个任务编号,在任务中打印出是哪一个线程执行了任务
 */
class MyRunnale3 implements Runnable{
    private int id;

    public MyRunnale3(int id) {
        this.id = id;
    }

    @Override
    public void run() {
        //获取线程的名称,打印一句话
        String name = Thread.currentThread().getName();
        System.out.println(name+"执行了任务..."+id);
    }
}

JDK API中的方法摘要

类型 方法 参数
boolean awaitTermination(long timeout, TimeUnit unit) 请求关闭、发生超时或者当前线程中断,无论哪一个首先发生之后,都将导致阻塞,直到所有任务完成执行。
List<Future> invokeAll(Collection<? extends Callable> tasks) 执行给定的任务,当所有任务完成时,返回保持任务状态和结果的 Future 列表。
List<Future> invokeAll(Collection<? extends Callable> tasks, long timeout, TimeUnit unit) 执行给定的任务,当所有任务完成或超时期满时(无论哪个首先发生),返回保持任务状态和结果的 Future 列表。
T invokeAny(Collection<? extends Callable> tasks) 执行给定的任务,如果某个任务已成功完成(也就是未抛出异常),则返回其结果。
T invokeAny(Collection<? extends Callable> tasks, long timeout, TimeUnit unit) 执行给定的任务,如果在给定的超时期满前某个任务已成功完成(也就是未抛出异常),则返回其结果。
boolean isShutdown() 如果此执行程序已关闭,则返回 true。
boolean isTerminated() 如果关闭后所有任务都已完成,则返回 true。
void shutdown() 启动一次顺序关闭,执行以前提交的任务,但不接受新任务。
List shutdownNow() 试图停止所有正在执行的活动任务,暂停处理正在等待的任务,并返回等待执行的任务列表。
Future submit(Callable task) 提交一个返回值的任务用于执行,返回一个表示任务的未决结果的 Future。
Future<?> submit(Runnable task) 提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future。
Future submit(Runnable task, T result) 提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future。

测试方法shutdown和shutdownNow

/**
 * 练习Executors获取ExecutorService,然后调用方法,测试关闭线程池的方法;
 * 1.shutdown();
 * 2.shutdownNow();
 */
public class MyTest04_shutdown {
    public static void main(String[] args) {
//        test01();
        test02();
    }
    //newSingleThreadExecutor方法只有一个线程
    private static void test01() {
        //使用工厂类获取线程池对象(newSingleThreadExecutor方法)
        ExecutorService es = Executors.newSingleThreadExecutor();
        //提交任务
        for (int i=1;i<10;i++){
            es.submit(new MyRunnale4(i));
        }
        //关闭线程池,仅仅是不在接收新的任务,以前的任务还好继续执行
        es.shutdown();
        //es.submit(new MyRunnale4(999));//一旦关闭不能再提交新的任务了
    }
    private static void test02() {
        //使用工厂类获取线程池对象(newSingleThreadExecutor)
        ExecutorService es = Executors.newSingleThreadExecutor(new ThreadFactory() {
            int n=1;
            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r,"自定义的线程名称"+n++);
            }
        });
        //提交任务
        for (int i=1;i<10;i++){
            es.submit(new MyRunnale4(i));
        }
        //立刻关闭线程池,如果线程池中还有缓存的任务没有执行,则取消执行,并返回这些任务(停止后也不可以提交)
        List<Runnable> runnables = es.shutdownNow();
        System.out.println(runnables);
    }

}

/**
 * 任务类,包含一个任务编号,在任务中打印出是哪一个线程执行了任务
 */
class MyRunnale4 implements Runnable{
    private int id;

    public MyRunnale4(int id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "MyRunnale4{" +
                "id=" + id +
                '}';
    }

    @Override
    public void run() {
        //获取线程的名称,打印一句话
        String name = Thread.currentThread().getName();
        System.out.println(name+"执行了任务..."+id);

    }
}

猜你喜欢

转载自blog.csdn.net/SkyCloud_/article/details/108414147