乐趣区

关于android:Java的线程和线程池的以及Executor线程框架理解

Java 的线程和线程池的了解

一:概念

在 Java 中,应用线程来异步执行工作。Java 的线程既是工作单元,也是执行机制。从 JDK 5 开始,把工作单元与执行机制拆散开来。工作单元包含 Runnable 和 Callable,而执行机制由 Executor 框架提供。

二:什么是 Executor 框架?

咱们晓得线程池就是线程的汇合,线程池集中管理线程,以实现线程的重用,升高资源耗费,进步响应速度等。线程用于执行异步工作,单个的线程既是工作单元也是执行机制,从 JDK1.5 开始,为了把工作单元与执行机制分来到,Executor 框架诞生了,他是一个用于对立创立与运行的接口。Executor 框架实现的就是线程池的性能

三:Executor 的构造

Executor 框架次要由 3 大部分组成如下。
1. 工作:包含被执行工作须要实现的接口:Runnable 接口或 Callable 接口。
2. 工作的执行:包含工作执行机制的外围接口 Executor,以及继承自 Executor 的 ExecutorService 接口。Executor 框架有两个要害类实现了 ExecutorService 接口(ThreadPoolExecutor 和 ScheduledThreadPoolExecutor)。
3. 异步计算的后果:包含接口 Future 和实现 Future 接口的 FutureTask 类。
Executor 框架蕴含的次要的类与接口如下图所示

四:对框架的了解

Executor 是一个接口,它是 Executor 框架的根底,它将工作的提交与工作的执行拆散开来

// 我了解的这是一个定义线程一个行为,工作执行,具体交由其实现实现
public interface Executor {void execute(Runnable command);
}

ExecutorService 也是一个接口 继承 Executor 接口 扩大 Executor

public interface ExecutorService extends Executor {
// 进行接管新工作,原来的工作继续执行
 void shutdown();
// 进行接管新工作,原来的工作进行执行
List<Runnable> shutdownNow();
// 接管的参数不一样 submit()能够承受 runnable 无返回值和 callable 有返回值
execute()承受 runnable 无返回值
<T> Future<T> submit(Callable<T> task);
}

AbstractExecutorService 是一个抽象类 实现 ExecutorService 接口扩大性能
ScheduledExecutorService(提早的线程池服务) 是一个接口 继承 ExecutorService 接口扩大性能
线程池外围类:
ThreadPoolExecutor 继承 AbstractExecutorService 的线程池类

public class ThreadPoolExecutor extends AbstractExecutorService {

// 构造方法
//corePoolSize 外围线程 指定了线程池中的线程数量,它的数量决定了增加的工作是开拓新的线程去执行,还是放到 workQueue 工作队列中去;//maximumPoolSize 指定了线程池中的最大线程数量,这个参数会依据你应用的 workQueue 工作队列的类型,决定线程池会开拓的最大线程数量;//keepAliveTime 当线程池中闲暇线程数量超过 corePoolSize 时,多余的线程会在多长时间内被销毁;(闲暇线程包活工夫)//unit:keepAliveTime 的单位
//workQueue: 工作队列,被增加到线程池中,但尚未被执行的工作;它个别分为间接提交队列、有界工作队列、无界工作队列、优先工作队列几种;(阻塞队列长度设置为 Integer.MAX_VALUE)//threadFactory: 线程工厂,用于创立线程,个别用默认即可;//handler: 回绝策略;当工作太多来不及解决时,如何回绝工作;public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              RejectedExecutionHandler handler) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), handler);
    }
}
// 例如线程池外围线程数为 1,最大线程数为 10,工作队列容量(阻塞队列)queueCapacity 也就是 BlockingQueue 工作 10 个
默认线程池的数量为 1,当工作不超过 10 个,会在工作队列排队期待线程池里一个线程解决
当工作 >10 个,会创立一个新的线程解决
当线程数达到最大线程数的时候 RejectedExecutionHandler(工作回绝处理器)回绝策略

RejectedExecutionHandler(回绝策略)接口有上面几个实现类 如果没有设置,默认是 AbortPolicy,会抛出异样。

AbortPolicy:抛弃工作,抛运行时异样
CallerRunsPolicy:执行工作
DiscardOldestPolicy:从队列中踢出最先进入队列(最初一个执行)的工作
DiscardPolicy:漠视,什么都不会产生

五:线程池的具体实现类

举例:Glide 的线程池实现类FifoPriorityThreadPoolExecutor 先进先出的策略线程池

// 先进先出的线程池策略的外围线程和最大线程的数量的是一样的
public class FifoPriorityThreadPoolExecutor extends ThreadPoolExecutor {

  public FifoPriorityThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAlive, TimeUnit timeUnit,
            ThreadFactory threadFactory, UncaughtThrowableStrategy uncaughtThrowableStrategy) {super(corePoolSize, maximumPoolSize, keepAlive, timeUnit, new PriorityBlockingQueue<Runnable>(), threadFactory);
        this.uncaughtThrowableStrategy = uncaughtThrowableStrategy;
    }
}

FifoPriorityThreadPoolExecutor 的对象有 sourceService 和 diskCacheService 2 个。
和 diskCacheService 的外围线程和最大线程数为 1 个
Glide 外面的会组装成 Engine 负责 EngineJob 工作治理

  if (engine == null) {engine = new Engine(memoryCache, diskCacheFactory, diskCacheService, sourceService);
        }

再由 Engine 组装成 Glide

return new Glide(engine, memoryCache, bitmapPool, context, decodeFormat);

六:线程池的分类

在 Executors 工厂类中提供了多种线程池,典型的有以下四种

  1. SingleThreadExecutor 单线程线程池
public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }
// 测试创立线程
 public static void singleThreadPool(){ExecutorService aa= Executors.newSingleThreadExecutor();
        // 创立工作
        Runnable runnable = new Runnable() {
            @Override
            public void run() {System.out.println("工作被执行, 线程:" + Thread.currentThread().getName());
            }
        };

        aa.execute(runnable);

    }

外围线程数为 1,最大线程数为 1,也就是说 SingleThreadExecutor 这个线程池中的线程数固定为 1。应用场景:当多个工作都须要拜访同一个资源的时候

  1. FixedThreadPool 固定容量线程池
 public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

// 栗子:创立线程,固定的线程池
 public static void fixedThreadPool(){ExecutorService aa= newFixedThreadPool(2);
        // 创立工作
        Runnable runnable = new Runnable() {
            @Override
            public void run() {System.out.println("工作被执行, 线程:" + Thread.currentThread().getName());
            }
        };
       aa.execute(runnable);

    }

外围线程数为 n,最大线程数为 n。应用场景:明确同时执行工作数量时。

  1. CachedThreadPool 缓存线程池

  public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

// 栗子:缓存线程池
public static void cachedThreadPool(){ExecutorService aa= Executors.newCachedThreadPool();
        // 创立工作
        Runnable runnable = new Runnable() {
            @Override
            public void run() {System.out.println("工作被执行, 线程:" + Thread.currentThread().getName());
            }
        };

        aa.execute(runnable);

    }

外围线程数为 0,最大线程数无下限,线程超时工夫 60 秒。应用场景:解决大量耗时较短的工作。

  1. ScheduledThreadPool 定时线程池
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {return new ScheduledThreadPoolExecutor(corePoolSize);
    }

 public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE,
              DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
              new DelayedWorkQueue());
    }

// 栗子:定时工作的创立线程池

public static void scheduledThreadPool(){ExecutorService aa= Executors.newScheduledThreadPool(1);
        // 创立工作
        Runnable runnable = new Runnable() {
            @Override
            public void run() {System.out.println("工作被执行, 线程:" + Thread.currentThread().getName());
            }
        };

        aa.execute(runnable);

    }

外围线程数自定,最大线程数无下限。应用场景:解决延时工作

退出移动版