Java线程池(ThreadPoolExector)

创建线程池的方式

1. Executors.newCachedThreadPool()

public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
    ```
特点:
1. corePoolSize为0,核心线程数为0
2. maximumPoolSize为无限大,线程数可以无限大
3. keepAliveTime为60S,线程空闲时间超过60s会杀死
4.  SynchronousQueue队列,不存储东西的阻塞队列,拥有公平和非公平
```java
public SynchronousQueue() {
        this(false);
    }

2.Executors.newFixedThreadPool(int nThread)

public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

特点:

  1. corePoolSize为nThread,核心线程数为nThread
  2. maximumPoolSize为nThread
  3. keepAliveTime为0,说明没任务直接死掉
  4. 4.LinkedBlockingQueue 最大容量可以是integer.MAX_VALUE,会产生OOM

3.Executors.newSingleThreadExecutor()

public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

特点:

  1. corePoolSize为1,核心线程数为1
  2. maximumPoolSize为1
  3. keepAliveTime为0,说明没任务直接死掉
  4. LinkedBlockingQueue 最大容量可以是integer.MAX_VALUE,会产生OOM

4. Executors.newScheduledThreadPool(int corePoolSize)

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }
    public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
              new DelayedWorkQueue());
    }
    ```
特点:
    1. corePoolSize可以制定
	2.  maximumPoolSize为1
	3. keepAliveTime为0,说明没任务直接死掉,任务等待的时间
	4. DelayedWorkQueue 是一个无界队列,从队列中取到期的任务执行,执行完又放回队列
```java
    public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
                                                  long initialDelay, // 首次执行的延时时间
                                                  long period, //定时执行的间隔时间 
                                                  TimeUnit unit
                                               

自定义线程 ThreadPoolExecutor()

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

例子

线程池拒绝策略

  1. AbortPolicy :丢弃任务并抛出 RejectedExecutionException,线程池默认拒绝策略。直接抛异常让我们及时发现程序的情况,关键任务使用
  2. DiscardPolicy :丢弃任务,不抛异常,无关紧要任务可以使用
  3. DiscardOldestPolicy:丢弃前面在队列的任务,接收拒绝的任务
  4. CallerRunsPolicy:给提交任务的线程执行,如主线程
  5. 自定义拒绝策略
new RejectedExecutionHandler() {
            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                //打印丢弃的任务
                System.out.println("拒绝了" + r.toString() );
            }
        }

线程池五种状态

线程池用一个AtomictInteger 变量 ctl来表示线程池状态和线程池中线程个数,其中高3位表示线程状态,其余29位表示线程池的线程个数。
线程池一共有五种状态:
1. RUNNING
* 高3位为 -1
* 线程池初始化状态为RUNNING,创建就为这种状态
* 能够接收任务,运行已经接收的任务,从0开始
2. SHUTDOWN
* 高3位为 0
* 此状态下不接收新的任务,但继续处理已接收的任务
* 调用 threadPoolExecutor.shutdown(); 即可从RUNNING 变为 SHUTDOWN
3. STOP
* 高3位为 1
* 此状态不接收新的任务,也不继续处理已经接收的任务,还会中断正在处理的任务
* 调用threadPoolExecutor.shutdownNow();,从RUNNING 或者 SHUTDOWN 变为 STOP

		 void interruptIfStarted() {
            Thread t;
            if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
                try {
                    t.interrupt();
                } catch (SecurityException ignore) {
                }
            }
            ```
	4. TIDYING
		*3位为  2
		* 所有任务都终止后,ctl的线程数量都为0,则会变成此状态
		*SHUTDOWN状态下,阻塞队列为空当前也没有任务在执行时就会变为TIDYING
		* STOP状态下,没有任务在执行了就会变为TIDYING
	5. TERMINATED
		*3位为  3
		* 线程池关闭
		* TIDYING状态下,执行terminated()后变为TERMINATED
	![示意图](https://img-blog.csdnimg.cn/20210707211942877.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h1aWd1aWZ1aHVv,size_16,color_FFFFFF,t_70)
# 线程复用原理
先看看Worker类
```java
 private final class Worker
        extends AbstractQueuedSynchronizer
        implements Runnable
    {
        /**
         * This class will never be serialized, but we provide a
         * serialVersionUID to suppress a javac warning.
         */
        private static final long serialVersionUID = 6138294804551838833L;

        /** Thread this worker is running in.  Null if factory fails. */
        final Thread thread;
        /** Initial task to run.  Possibly null. */
        Runnable firstTask;
        /** Per-thread task counter */
        volatile long completedTasks;

        /**
         * Creates with given first task and thread from ThreadFactory.
         * @param firstTask the first task (null if none)
         */
        Worker(Runnable firstTask) {
            setState(-1); // inhibit interrupts until runWorker
            this.firstTask = firstTask;
            this.thread = getThreadFactory().newThread(this);
        }

        /** Delegates main run loop to outer runWorker  */
        public void run() {
            runWorker(this);
        }

        // Lock methods
        //
        // The value 0 represents the unlocked state.
        // The value 1 represents the locked state.

        protected boolean isHeldExclusively() {
            return getState() != 0;
        }

        protected boolean tryAcquire(int unused) {
            if (compareAndSetState(0, 1)) {
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }

        protected boolean tryRelease(int unused) {
            setExclusiveOwnerThread(null);
            setState(0);
            return true;
        }

        public void lock()        { acquire(1); }
        public boolean tryLock()  { return tryAcquire(1); }
        public void unlock()      { release(1); }
        public boolean isLocked() { return isHeldExclusively(); }

        void interruptIfStarted() {
            Thread t;
            if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
                try {
                    t.interrupt();
                } catch (SecurityException ignore) {
                }
            }
        }
    }

方法流程

说明:worker类包装了Runnable对象,实现了Runnable接口,重写了run方法,重写的run方法是调用runWorker(),runWorker里面有不断从阻塞队列获取Runnable对象然后调用它的run方法。Thread.start()只能调用一次,一旦这个调用结束,则该线程就到了stop状态,不能再次调用start。而run方法却可以调用多次。

final void runWorker(Worker w) {
        Thread wt = Thread.currentThread();
        Runnable task = w.firstTask;
        w.firstTask = null;
        w.unlock(); // allow interrupts
        boolean completedAbruptly = true;
        try {
            while (task != null || (task = getTask()) != null) {
                w.lock();
                // If pool is stopping, ensure thread is interrupted;
                // if not, ensure thread is not interrupted.  This
                // requires a recheck in second case to deal with
                // shutdownNow race while clearing interrupt
                if ((runStateAtLeast(ctl.get(), STOP) ||
                     (Thread.interrupted() &&
                      runStateAtLeast(ctl.get(), STOP))) &&
                    !wt.isInterrupted())
                    wt.interrupt();
                try {
                    beforeExecute(wt, task);
                    Throwable thrown = null;
                    try {
                        task.run();
                    } catch (RuntimeException x) {
                        thrown = x; throw x;
                    } catch (Error x) {
                        thrown = x; throw x;
                    } catch (Throwable x) {
                        thrown = x; throw new Error(x);
                    } finally {
                        afterExecute(task, thrown);
                    }
                } finally {
                    task = null;
                    w.completedTasks++;
                    w.unlock();
                }
            }
            completedAbruptly = false;
        } finally {
            processWorkerExit(w, completedAbruptly);
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值