java 线程池的使用

虽然说RxJava 与RxAndroid 已经能很好的处理多线程的问题,但是我们还是要总结一下线程池的使用

为什么需要使用线程池?线程的频发创建,需要时间,也会加大系统的开销,最简单的办法就是复用,也因此产生线程池,产生线程池的核心就是ThreadPoolExecutor

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }

    
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             threadFactory, defaultHandler);
    }

   
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              RejectedExecutionHandler handler) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), handler);
    }

   
    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;
    }


可以看到其构造方式还是特别的多,简单解释几个参数的意义:

  

corePoolSize 线程池大小,当任务的线程数超过其值时就会放入到缓存队列中
maximumPoolSize 线程池最大线程数,表示线程池中最多能创建的线程数量
keepAliveTime 表示线程没有任务执行最等待多时时间而终止,条件:
1:当前线程池中的线程数>corePoolSize
2:allowCoreThreadTimeOut(booleanvalue)调用
TimeUnit 时间单位
BlockingQueue 阻塞队列,其子类非常多:
常用的用:ArrayBlockingQueue
                 LinkedBlockingQueue
                 SynchronousQueue
                LinkdeBlockingQueue

threadFactory 创建线程的工厂
handler ThreadPoolExecutor已经实现四个(内部类):分别是:
AbortPolicy//抛出异常
DiscardPolicy  //丢弃任务
DiscardOldestPolicy  //丢弃最前面的任务,然后执行新的任务
CallerRunsPolicy  //由线程处理任务
   


ThreadPoolExecutor常用的方法:

public void execute(Runnable command)
执行一个任务
Future<?> submit(Runnable task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);
执行一个任务
重载形式非常多,可以要求返回结果
可以是Future 可以有执行状态和返回值等
shutDown() interuppt空闲线程,会等待线程执行完成,不再执行新的任务
shutDownNow() interuppt所有线程,尝试终止正在执行的线程


实例:

package com.example;

import com.example.utils.LogUtils;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author xuanyouwu
 * @email [email protected]
 * @time 2016-05-04 16:38
 */
public class ThreadPoolStudy {
   static ThreadPoolExecutor threadPoolExecutor;
    public static void main(String[] args) throws Exception {

        threadPoolExecutor = new ThreadPoolExecutor(3, 10, 2, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(3));

        for (int i = 0; i < 100; i++) {
            threadPoolExecutor.execute(new Task());
        }
    }

    static class Task implements Runnable {

        @Override
        public void run() {
            LogUtils.d("------>excute:Thread:" + Thread.currentThread().getId()+"   PoolSiz:"+threadPoolExecutor.getPoolSize()+"  ActiveCount:"+threadPoolExecutor.getActiveCount()+"  queueSize:"
            +threadPoolExecutor.getQueue().size()+"   CompletedTaskCount:"+threadPoolExecutor.getCompletedTaskCount());
            try {
                Thread.currentThread().sleep(3000);
            } catch (InterruptedException e) {
            }
        }
    }
}


执行结果:

------>excute:Thread:12   PoolSiz:5  ActiveCount:6  queueSize:3   CompletedTaskCount:0
Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task com.example.ThreadPoolStudy$Task@5cad8086 rejected from java.util.concurrent.ThreadPoolExecutor@6e0be858[Running, pool size = 10, active threads = 10, queued tasks = 3, completed tasks = 0]
------>excute:Thread:17   PoolSiz:9  ActiveCount:9  queueSize:3   CompletedTaskCount:0
------>excute:Thread:20   PoolSiz:9  ActiveCount:10  queueSize:3   CompletedTaskCount:0
------>excute:Thread:15   PoolSiz:7  ActiveCount:7  queueSize:3   CompletedTaskCount:0
------>excute:Thread:14   PoolSiz:6  ActiveCount:6  queueSize:3   CompletedTaskCount:0
------>excute:Thread:18   PoolSiz:9  ActiveCount:9  queueSize:3   CompletedTaskCount:0
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2047)
------>excute:Thread:19   PoolSiz:9  ActiveCount:9  queueSize:3   CompletedTaskCount:0
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:823)

出现了异常,

java 线程池的使用_第1张图片

从源码中可以看到 推荐使用Excutors来创建线程池

public static ExecutorService newWorkStealingPool() {
    return new ForkJoinPool
        (Runtime.getRuntime().availableProcessors(),
         ForkJoinPool.defaultForkJoinWorkerThreadFactory,
         null, true);
}
可惜是java 1.8才有的
 
 
推荐下面几种写法:
/**
         * return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
         60L, TimeUnit.SECONDS,
         new SynchronousQueue<Runnable>());
         */
        Executors.newCachedThreadPool();

        /**
         *    return new ThreadPoolExecutor(nThreads, nThreads,
         0L, TimeUnit.MILLISECONDS,
         new LinkedBlockingQueue<Runnable>());
         */
        Executors.newFixedThreadPool(100);

        /**
         *  return new FinalizableDelegatedExecutorService
         (new ThreadPoolExecutor(1, 1,
         0L, TimeUnit.MILLISECONDS,
         new LinkedBlockingQueue<Runnable>()));
         */
        Executors.newSingleThreadExecutor();


用法实例:newCachedThreadPool

 ExecutorService executorService = Executors.newCachedThreadPool();
        for(int i=0;i<50;i++)
        {
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.currentThread().sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    LogUtils.d("---------->Thread:"+Thread.currentThread().getId());
                }
            });
        }

运行结果:

---------->Thread:13
---------->Thread:21
---------->Thread:15
---------->Thread:18
---------->Thread:19
---------->Thread:17
---------->Thread:20
---------->Thread:12
---------->Thread:16
---------->Thread:14
---------->Thread:30
---------->Thread:29
---------->Thread:28
---------->Thread:27
---------->Thread:25
---------->Thread:26
---------->Thread:24
---------->Thread:23
---------->Thread:22
---------->Thread:38
---------->Thread:41
---------->Thread:40
---------->Thread:39
---------->Thread:37
---------->Thread:34
---------->Thread:36
---------->Thread:35
---------->Thread:31
---------->Thread:33
---------->Thread:32
---------->Thread:46
---------->Thread:50
---------->Thread:48
---------->Thread:49
---------->Thread:51
---------->Thread:44
---------->Thread:45
---------->Thread:42
---------->Thread:43
---------->Thread:47
---------->Thread:55
---------->Thread:61
---------->Thread:58
---------->Thread:57
---------->Thread:60
---------->Thread:59
---------->Thread:56
---------->Thread:54
---------->Thread:52
---------->Thread:53


例子:固定线程newFixedThreadPool

 ExecutorService executorService = Executors.newFixedThreadPool(3);
        for(int i=0;i<50;i++)
        {
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.currentThread().sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    LogUtils.d("---------->Thread:"+Thread.currentThread().getId());
                }
            });
        }
        executorService.shutdown();
运行结果:

---------->Thread:14
---------->Thread:12
---------->Thread:13
---------->Thread:13
---------->Thread:14
---------->Thread:12
---------->Thread:13
---------->Thread:14
---------->Thread:12
---------->Thread:12

.....

例子:newSingleThreadExecutor

 executorService=Executors.newSingleThreadExecutor();
        for(int i=0;i<50;i++)
        {
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.currentThread().sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    LogUtils.d("---------->Thread:"+Thread.currentThread().getId());
                }
            });
        }
        executorService.shutdown();

运行结果:

---------->Thread:12
---------->Thread:12
---------->Thread:12
---------->Thread:12
---------->Thread:12

......


线程的优先级:

 /**  * The minimum priority that a thread can have.  */  public final static int MIN_PRIORITY = 1;

/**  * The default priority that is assigned to a thread.  */  public final static int NORM_PRIORITY = 5;

 /**  * The maximum priority that a thread can have.  */  public final static int MAX_PRIORITY = 10;
 
 
设置线程的优先级需要ThreadFacotry
 
 
 ThreadFactory threadFactory_MAX_PRIORITY = new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                Thread thread = new Thread(r);
                thread.setPriority(Thread.MAX_PRIORITY);
                return thread;
            }
        };

        ThreadFactory threadFactory_MIN_PRIORITY = new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                Thread thread = new Thread(r);
                thread.setPriority(Thread.MIN_PRIORITY);
                return thread;
            }
        };

        ThreadFactory threadFactory_NORMAL_PRIORITY = new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                Thread thread = new Thread(r);
                thread.setPriority(Thread.NORM_PRIORITY);
                return thread;
            }
        };

        ExecutorService executorService_MAX = Executors.newCachedThreadPool(threadFactory_MAX_PRIORITY);
        for (int i = 0; i < 10; i++) {
            executorService_MAX.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.currentThread().sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    LogUtils.d("---------->Thread:" + Thread.currentThread().getId() + "  threadPripiry:" + Thread.currentThread().getPriority());
                }
            });
        }
        executorService_MAX.shutdown();

        ExecutorService executorService_NOR = Executors.newCachedThreadPool(threadFactory_NORMAL_PRIORITY);
        for (int i = 0; i < 10; i++) {
            executorService_NOR.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.currentThread().sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    LogUtils.d("---------->Thread:" + Thread.currentThread().getId() + "  threadPripiry:" + Thread.currentThread().getPriority());
                }
            });
        }
        executorService_NOR.shutdown();


        ExecutorService executorService_MIN = Executors.newCachedThreadPool(threadFactory_MIN_PRIORITY);
        for (int i = 0; i < 10; i++) {
            executorService_MIN.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.currentThread().sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    LogUtils.d("---------->Thread:" + Thread.currentThread().getId() + "  threadPripiry:" + Thread.currentThread().getPriority());
                }
            });
        }
        executorService_MIN.shutdown();

运行结果:

---------->Thread:16  threadPripiry:10
---------->Thread:15  threadPripiry:10
---------->Thread:18  threadPripiry:10
---------->Thread:21  threadPripiry:10
---------->Thread:14  threadPripiry:10
---------->Thread:26  threadPripiry:5
---------->Thread:19  threadPripiry:10
---------->Thread:20  threadPripiry:10
---------->Thread:13  threadPripiry:10
---------->Thread:17  threadPripiry:10
---------->Thread:12  threadPripiry:10
---------->Thread:30  threadPripiry:5
---------->Thread:29  threadPripiry:5
---------->Thread:31  threadPripiry:5
---------->Thread:28  threadPripiry:5
---------->Thread:24  threadPripiry:5
---------->Thread:27  threadPripiry:5
---------->Thread:25  threadPripiry:5
---------->Thread:22  threadPripiry:5
---------->Thread:23  threadPripiry:5
---------->Thread:32  threadPripiry:1
---------->Thread:34  threadPripiry:1
---------->Thread:33  threadPripiry:1
---------->Thread:35  threadPripiry:1
---------->Thread:39  threadPripiry:1
---------->Thread:36  threadPripiry:1
---------->Thread:38  threadPripiry:1
---------->Thread:37  threadPripiry:1
---------->Thread:41  threadPripiry:1
---------->Thread:40  threadPripiry:1

你可能感兴趣的:(java 线程池的使用)