线程

java并发编程(3)线程池

2017-09-13  本文已影响25人  monkey01

该篇是本系列的第三篇,本篇主要介绍日常开发过程中常用的线程池,在jdk中已经给我们提供了很多线程池创建方法,可以方便的快速创建线程,最常用的创建线程池的方法是调用Executors的new系列方法newFixedThreadPool()、newCachedThreadPool()、newSingleThreadExecutor()等,这些方法看名字就很好理解具体含义,newFixedThreadPool表示创建一个固定线程的线程池,newCachedThreadPool表示根据实际创建的线程数进行动态创建线程池,newSingleThreadExecutor为创建一个只有一个线程的线程池,这些所有的创建线程池的方法都可以将ThreadFactory作为创建线程池构造函数的入参,在很多场合我们需要自定义线程工厂来满足我们的需求。

创建固定线程池实例,入参为线程池数量:

ExecutorService es = Executors.newFixedThreadPool(5);

自定义线程池:

ExecutorService es2 = new ThreadPoolExecutor(5, 10, 1000, TimeUnit.MILLISECONDS,
                new SynchronousQueue<Runnable>(), new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                Thread t = new Thread(r);
                System.out.println("create " + t);
                return t;
            }
        }, new RejectedExecutionHandler() {
            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                System.out.println(r.toString() + " is discard!");
            }
        });

ThreadPoolExecutor的构造函数如下,:

ThreadPoolExecutor(int corePoolSize,//核心线程数,启动时候会启动这个数量的线程,也不会删除线程
                int maximumPoolSize,//最大线程池数量
                long keepAliveTime,//线程保持时间
                TimeUnit unit,//保持时间单位
                BlockingQueue<Runnable> workQueue,//等待队列,默认使用SynchronousQueue就可以
                ThreadFactory threadFactory,//可以自定义ThreadFactory进行特殊处理
                RejectedExecutionHandler handler)//超出线程后的拒绝策略,可以自定义拒绝的处理方式,用的比较多的策略就是放弃

通过下面的例子分别创建了两个线程池,实例es是创建的固定线程数的线程池,循环10次提交线程,因为线程池数量为5,我们发现打出的线程分两批显示,5个5个显示出来,并且线程id是复用的,如下显示:

1505295665359:thread id = 9
1505295665359:thread id = 10
1505295665359:thread id = 11
1505295665359:thread id = 12
1505295665359:thread id = 13
1505295666361:thread id = 11
1505295666361:thread id = 12
1505295666362:thread id = 13
1505295666362:thread id = 10
1505295666362:thread id = 9

实例es2是自定义线程池,自定义的丢弃策略为打印丢弃线程直接丢弃不处理,线程池大小为10,线程循环执行20次,有10次线程处理被丢弃,执行结果如下:

create Thread[Thread-0,5,main]
create Thread[Thread-1,5,main]
1505295922428:thread id = 9
create Thread[Thread-2,5,main]
1505295922428:thread id = 10
create Thread[Thread-3,5,main]
1505295922428:thread id = 11
create Thread[Thread-4,5,main]
1505295922429:thread id = 12
create Thread[Thread-5,5,main]
1505295922429:thread id = 13
create Thread[Thread-6,5,main]
1505295922429:thread id = 14
create Thread[Thread-7,5,main]
1505295922429:thread id = 15
create Thread[Thread-8,5,main]
1505295922430:thread id = 16
create Thread[Thread-9,5,main]
1505295922430:thread id = 17
1505295922430:thread id = 18
java.util.concurrent.FutureTask@6f94fa3e is discard!
java.util.concurrent.FutureTask@5e481248 is discard!
java.util.concurrent.FutureTask@66d3c617 is discard!
java.util.concurrent.FutureTask@63947c6b is discard!
java.util.concurrent.FutureTask@2b193f2d is discard!
java.util.concurrent.FutureTask@355da254 is discard!
java.util.concurrent.FutureTask@4dc63996 is discard!
java.util.concurrent.FutureTask@d716361 is discard!
java.util.concurrent.FutureTask@6ff3c5b5 is discard!
java.util.concurrent.FutureTask@3764951d is discard!

上面例子的全部代码如下:

public class ThreadPoolBasic {

    public static void main(String[] args) throws InterruptedException {

        MyThread myThread = new MyThread();
        MyThread myThread2 = new MyThread();
        ExecutorService es = Executors.newFixedThreadPool(5);
        for(int i=0; i<10; i++){
            es.submit(myThread);
        }

        ExecutorService es2 = new ThreadPoolExecutor(5, 10, 1000, TimeUnit.MILLISECONDS,
                new SynchronousQueue<Runnable>(), new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                Thread t = new Thread(r);
                System.out.println("create " + t);
                return t;
            }
        }, new RejectedExecutionHandler() {
            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                System.out.println(r.toString() + " is discard!");
            }
        });
        System.out.println("====custom threadfactoty====");
        for(int i=0; i<20; i++){
            es2.submit(myThread2);
        }

        es.shutdown();
        es2.shutdown();
    }

    public static class MyThread implements Runnable{
        @Override
        public void run() {
            System.out.println(System.currentTimeMillis() + ":thread id = " + Thread.currentThread().getId());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }

}

通过这个例子是不是发现jdk的线程池使用很简单,自己动手写个demo尝试下吧。

上一篇 下一篇

猜你喜欢

热点阅读