美文网首页
java线程-线程池

java线程-线程池

作者: Duzzi | 来源:发表于2018-11-15 20:35 被阅读14次

先明确一些概念

进程与线程

进程

进程是正在执行的计算机程序的实例,是计算机进行资源分配和调度的基本单位。进程可以由多个线程组成。

线程

线程是程序执行的最小单位,多个线程可以存在于同一个进程内,并发执行和共享系统资源,而不同进程不共享这些资源。

并行与并发

并行

指的是在多个处理器(或者多核)上同时处理多个任务

并发

指的是在一个处理器上同时处理多个任务

为什么要用线程池?

new thread()的弊端

  • 线程的创建和销毁会带来一定的开销
  • 缺乏统一管理,可能无限制的创建线程,相互之间的竞争可能占用系统过多资源
  • 缺乏更多功能,比如定时执行,定期执行,线程中断

线程池的好处

  • 可重复利用已创建好的线程,减少对象频繁创建销毁带来的性能开销
  • 可有效控制线程的最大并放弃啊数,提高系统资源的使用率,通知避免资源过度竞争,避免堵塞
  • 提供定时执行,定期执行,单线程,并发数控制等功能

java中的线程池

几个重要的类

接口Executor

void execute(Runnable command);

接口ExecutorService继承Executor,并扩展了一些方法

抽象类AbstractExecutorService实现了ExecutorService的部分方法

具体实现类ThreadPoolExecutor

Android中的线程池都是直接或间接通过配置ThreadPoolExecutor 来实现不同特性的线程池

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler) {
    if (corePoolSize < 0 ||
        maximumPoolSize <= 0 ||
        maximumPoolSize < corePoolSize ||
        keepAliveTime < 0)
        throw new IllegalArgumentException();
    if (workQueue == null || threadFactory == null || handler == null)
        throw new NullPointerException();
    this.corePoolSize = corePoolSize;
    this.maximumPoolSize = maximumPoolSize;
    this.workQueue = workQueue;
    this.keepAliveTime = unit.toNanos(keepAliveTime);
    this.threadFactory = threadFactory;
    this.handler = handler;
}
  • int corePoolSize,

核心线程数,除非allowCoreThreadTimeOut被设置为true,否则它闲着也不会死

  • int maximumPoolSize,

最大线程数,活动线程数量超过它,后续任务就会排队

  • long keepAliveTime,

超时时长,作用于非核心线程(allowCoreThreadTimeOut被设置为true时也会同时作用于核心线程),闲置超时便被回收

  • TimeUnit unit,

枚举类型,设置keepAliveTime的单位,有TimeUnit.MILLISECONDS(ms)、TimeUnit. SECONDS(s)等

  • BlockingQueue<Runnable> workQueue,

缓冲任务队列,线程池的execute方法会将Runnable对象存储起来

  • ThreadFactory threadFactory)

线程工厂接口,只有一个new Thread(Runnable r)方法,可为线程池创建新线程

Executors这个类已经提供了常用的四种线程池创建

1. newFixedThreadPool
2. newCachedThreadPool
3. newScheduledThreadPool
4. newSingleThreadExecutor

newFixedThreadPool

创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。可以通过Runtime.getRuntime().availableProcessors()查看。

创建一个在共享的无界队列中使用固定数量的线程运行的线程池。在任何时候,有最多n个线程将处理任务。
如果所有线程都处于活动状态时,提交额外的任务,他们会在队列中等待,直到有一个线程可用。
如果在执行过程中出现故障,任何线程都会终止。如果需要执行后续任务,新的任务将取代它的位置。线程池中的线程会一直存在,直到它显式为止(调用shutdown)

ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(3);
for (int i = 0; i < 10; i++) {
    try {
        Thread.sleep(500);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    final int finalI = i;
    newFixedThreadPool.execute(new Runnable() {
        @Override
        public void run() {
            System.out.println("newFixedThreadPool: " + Thread.currentThread() + " "+ finalI);
        }
    });
}

打印结果:

newFixedThreadPool: Thread[pool-1-thread-1,5,main] 0
newFixedThreadPool: Thread[pool-1-thread-2,5,main] 1
newFixedThreadPool: Thread[pool-1-thread-3,5,main] 2
newFixedThreadPool: Thread[pool-1-thread-1,5,main] 3
newFixedThreadPool: Thread[pool-1-thread-2,5,main] 4
newFixedThreadPool: Thread[pool-1-thread-3,5,main] 5
newFixedThreadPool: Thread[pool-1-thread-1,5,main] 6
newFixedThreadPool: Thread[pool-1-thread-2,5,main] 7
newFixedThreadPool: Thread[pool-1-thread-3,5,main] 8
newFixedThreadPool: Thread[pool-1-thread-1,5,main] 9

newCachedThreadPool

创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。

ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {

    final int finalI = i;
    newCachedThreadPool.execute(new Runnable() {
        @Override
        public void run() {
            System.out.println("testCacheThreadPool:  " + Thread.currentThread() + " "+ finalI);
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    });
}

打印结果:

testCacheThreadPool:  Thread[pool-1-thread-1,5,main] 0
testCacheThreadPool:  Thread[pool-1-thread-5,5,main] 4
testCacheThreadPool:  Thread[pool-1-thread-3,5,main] 2
testCacheThreadPool:  Thread[pool-1-thread-4,5,main] 3
testCacheThreadPool:  Thread[pool-1-thread-2,5,main] 1
testCacheThreadPool:  Thread[pool-1-thread-7,5,main] 6
testCacheThreadPool:  Thread[pool-1-thread-6,5,main] 5
testCacheThreadPool:  Thread[pool-1-thread-8,5,main] 7
testCacheThreadPool:  Thread[pool-1-thread-9,5,main] 8
testCacheThreadPool:  Thread[pool-1-thread-10,5,main] 9

这里并没有复用

newScheduledThreadPool

创建一个定长线程池,支持定时及周期性任务执行。

ScheduledExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(3);
for (int i = 0; i < 10; i++) {
    final int finalI = i;
    newScheduledThreadPool.schedule(new Runnable() {
        @Override
        public void run() {
            System.out.println("newScheduledThreadPool: " + Thread.currentThread() + " "+ finalI);
        }
    },2, TimeUnit.SECONDS);
}

打印结果:

newScheduledThreadPool: Thread[pool-1-thread-1,5,main] 0
newScheduledThreadPool: Thread[pool-1-thread-2,5,main] 2
newScheduledThreadPool: Thread[pool-1-thread-3,5,main] 1
newScheduledThreadPool: Thread[pool-1-thread-2,5,main] 4
newScheduledThreadPool: Thread[pool-1-thread-1,5,main] 3
newScheduledThreadPool: Thread[pool-1-thread-2,5,main] 6
newScheduledThreadPool: Thread[pool-1-thread-1,5,main] 7
newScheduledThreadPool: Thread[pool-1-thread-3,5,main] 5
newScheduledThreadPool: Thread[pool-1-thread-1,5,main] 9
newScheduledThreadPool: Thread[pool-1-thread-2,5,main] 8

newSingleThreadExecutor

创建一个在无界队列使用单个工作线程运行的执行器。但是要注意,如果这个单线程在shutdown之前因为故障导致线程终止,则在需要执行后续任务的时候将创建一个新的线程取代它。任务是被确保按顺序执行的,任意时刻只会激活一个任务。与newFixedThreadPool(1)不同的是,返回的执行器

ExecutorService newSingledThreadPool = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
    try {
        Thread.sleep(500);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    final int finalI = i;
    newSingledThreadPool.execute(new Runnable() {
        @Override
        public void run() {
            System.out.println("newSingledThreadPool: " + Thread.currentThread() + " "+ finalI);
        }
    });
}

打印结果:

newSingledThreadPool: Thread[pool-1-thread-1,5,main] 0
newSingledThreadPool: Thread[pool-1-thread-1,5,main] 1
newSingledThreadPool: Thread[pool-1-thread-1,5,main] 2
newSingledThreadPool: Thread[pool-1-thread-1,5,main] 3
newSingledThreadPool: Thread[pool-1-thread-1,5,main] 4
newSingledThreadPool: Thread[pool-1-thread-1,5,main] 5
newSingledThreadPool: Thread[pool-1-thread-1,5,main] 6
newSingledThreadPool: Thread[pool-1-thread-1,5,main] 7
newSingledThreadPool: Thread[pool-1-thread-1,5,main] 8
newSingledThreadPool: Thread[pool-1-thread-1,5,main] 9

这里都是用的同一个线程

相关文章

网友评论

      本文标题:java线程-线程池

      本文链接:https://www.haomeiwen.com/subject/lwjufqtx.html