package A_ShangGuiGu.Thread.ThreadTest;

import java.util.concurrent.*;

/**
 * 创建线程的方式四:使用线程池。
 * 线程池的好处:
 *   1.提高响应速度(减少了创建线程的时间)
 *   2.降低资源消耗(重复利用线程池中线程,不需要每次都创建)
 *   3.便于线程管理:
 *          1)corePoolSize:核心池的大小
 *          2)maximumPoolSize:最大线程数
 *          3)keepAliveTime:线程没有任务时最多保持多长时间关闭。
 *
 * 线程池的api:ExecutorService和Executors
 * 1.ExecutorService:真正的线程池接口。
 *      1)void execute(Runnable command):执行任务/命令。没有返回值,一般用于Runnable接口的线程
 *      2)<T>future<T>submit(Callable<T>Task):执行任务,有返回值,一般用于执行Callable接口的线程
 *      3)void Shutdown:关闭连接池
 * 2.Executors工具类子类:
 *      1)Executors.newCachedThreadPool():创建一个可根据需要创建新线程的线程池。
 *      2)Executors.newFixedThreadPool():创建一个可重用固定线程数的线程池。(线程池里线程数量可以自己设置)
 *      3)Executors.newSingleThreadExecutor():创建一个只有一个线程的线程池。
 *      4)Executors.newScheduledThreadPool():创建一个线程池,他可以安排在给定延迟后运行命令或者定期运行命令。
 *      5)
 */
//创建一个线程
class Number01 implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i <= 100; i++) {
            if (i%2==0){
                System.out.println(Thread.currentThread().getName()+":"+i);
            }
        }
    }
}
class Number02 implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i <= 100; i++) {
            if (i%2!=0){
                System.out.println(Thread.currentThread().getName()+":"+i);
            }
        }
    }
}

public class ThreadPool {
    public static void main(String[] args) {

        //1.提供一个指定线程数量的线程池
        //这个创建的线程池是使用的ExecutorService接口,里面的属性是常量,能修改的很少。ExecutorService是一个很大的类
        ExecutorService service = Executors.newFixedThreadPool(10);

        //将ExecutorService类型的对象向下转型(需要强制转型)后,就可以对转型后的线程池修改属性了
        ThreadPoolExecutor service1 = (ThreadPoolExecutor) service;

        //service1.setKeepAliveTime(5, TimeUnit.SECONDS);


        //2.将线程类实例化一个对象
        Number01 number01 = new Number01();
        Number02 number02 = new Number02();

        //3.执行指定的线程对象的操作
        service1.execute(number01);
        service1.execute(number02);
        //4.执行结束后需要关闭
        service1.shutdown();
    }
}