J.U.C之線程池07:源碼解析-完整解釋

package com.netty.learning;

import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class ThreadPoolExecutor extends AbstractExecutorService {

    /**
     * 用于記錄線程池池的 狀態(tài)和當(dāng)前待work線程數(shù)量
     * 前3位記錄線程池狀態(tài)
     * 后29位記錄運(yùn)行work數(shù)量
     */
    private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));

    /** Java 中Integer 類型長(zhǎng)度為32位诉儒,線程池用一個(gè)int類型的前3位表示線程池的狀態(tài)**/
    private static final int COUNT_BITS = Integer.SIZE - 3;

    /** 用來(lái)計(jì)算出當(dāng)前線程池狀態(tài)中間變量凳忙,同時(shí)也表示work最大數(shù)量
     *  00011111 11111111 11111111 11111111
     **/
    private static final int CAPACITY   = (1 << COUNT_BITS) - 1;

    /** -----------------線程池狀態(tài)----------------- **/

    /**
     * 線程池RUNNING狀態(tài),當(dāng)前狀態(tài)下線程池可以接收新的任務(wù),對(duì)新接收的任務(wù)進(jìn)行處理霎挟,
     * 工廠正常運(yùn)行
     *
     * -1 二進(jìn)制 11111111111111111111111111111111 左移動(dòng) 29位 前三位 111
     */
    private static final int RUNNING    = -1 << COUNT_BITS;

    /**
     * 線程池SHUTDOWN狀態(tài),當(dāng)前狀態(tài)下線程池不在接收新任務(wù),對(duì)之前接收的任務(wù)(其中包括還在隊(duì)列等待和正在執(zhí)行的任務(wù))
     *  工廠不在接收新的訂單,工廠運(yùn)行出現(xiàn)了問(wèn)題
     *
     *  0 二進(jìn)制 00000000000000000000000000000000 左移動(dòng) 29位 前三位 000
     */
    private static final int SHUTDOWN   =  0 << COUNT_BITS;

    /**
     * 線程池STOP狀態(tài),當(dāng)前狀態(tài)下線程池不在接收新任務(wù)艺栈,對(duì)之前接收的任務(wù)存在隊(duì)列沒(méi)有處理的不在處理敢艰,正在執(zhí)行做中斷
     *  工廠不在接收新的訂單,工廠要倒閉了
     *
     *  1 二進(jìn)制 00000000000000000000000000000001 左移動(dòng) 29位 前三位 001
     */
    private static final int STOP       =  1 << COUNT_BITS;

    /**
     * 線程池TIDYING狀態(tài),當(dāng)前沒(méi)有待執(zhí)行的任務(wù),等待執(zhí)行注冊(cè)到JVM的鉤子函數(shù)terminated()
     *  工廠走倒閉程序诡曙,需要做最后清理工作
     *
     *  2 二進(jìn)制 00000000000000000000000000000010 左移動(dòng) 29位 前三位 010
     */
    private static final int TIDYING    =  2 << COUNT_BITS;

    /**
     * 執(zhí)行完VM的鉤子函數(shù)terminated()
     *  工廠關(guān)閉
     *  3 二進(jìn)制 00000000000000000000000000000011 左移動(dòng) 29位 前三位 011
     */
    private static final int TERMINATED =  3 << COUNT_BITS;

    /** 計(jì)算獲取當(dāng)前線程池狀態(tài) **/
    private static int runStateOf(int c)     { return c & ~CAPACITY; }

    /** 計(jì)算獲取當(dāng)前運(yùn)行work數(shù)量**/
    private static int workerCountOf(int c)  { return c & CAPACITY; }


    /**
     * 即根據(jù)線程池的狀態(tài)和worker數(shù)量合并成整形 ctl
     */
    private static int ctlOf(int rs, int wc) { return rs | wc; }


    /** 判斷當(dāng)前線程池是否小于s,c表示當(dāng)前線程池狀態(tài) **/
    private static boolean runStateLessThan(int c, int s) {
        return c < s;
    }

    /** 判斷當(dāng)前線程池是否大于等于s,c表示當(dāng)前線程池狀態(tài) **/
    private static boolean runStateAtLeast(int c, int s) {
        return c >= s;
    }

    /** 判斷當(dāng)前線程池是否正在正常運(yùn)行  RUNNING狀態(tài)**/
    private static boolean isRunning(int c) {
        return c < SHUTDOWN;
    }

    /**
     * 使用CAS增加線程池中work數(shù)量(后29位可以直接整數(shù)運(yùn)算)
     * 成功返回true,失敗返回false
     */
    private boolean compareAndIncrementWorkerCount(int expect) {
        return ctl.compareAndSet(expect, expect + 1);
    }

    /**
     * 使用CAS減少線程池中work數(shù)量(后29位可以直接整數(shù)運(yùn)算)
     * 成功返回true,失敗返回false
     */
    private boolean compareAndDecrementWorkerCount(int expect) {
        return ctl.compareAndSet(expect, expect - 1);
    }

    /**
     * 使用CAS減少線程池中work數(shù)量(后29位可以直接整數(shù)運(yùn)算),失敗循環(huán)繼續(xù)嘗試直到成功
     */
    private void decrementWorkerCount() {
        do {} while (! compareAndDecrementWorkerCount(ctl.get()));
    }


    private final BlockingQueue<Runnable> workQueue;


    /**
     * 存放worker線程的集合
     */
    private final HashSet<Worker> workers = new HashSet<Worker>();


    /**
     * 控制ThreadPoolExecutor的全局可重入鎖
     */
    private final ReentrantLock mainLock = new ReentrantLock();



    /**
     * 控制ThreadPoolExecutor的全局可重入鎖
     */
    private final Condition termination = mainLock.newCondition();


    /**
     * 記錄work數(shù)量(片段值)
     */
    private int largestPoolSize;


    /**
     * 完成任務(wù)數(shù)量
     */
    private long completedTaskCount;


    /**
     * work線程構(gòu)造工廠
     */
    private volatile ThreadFactory threadFactory;


    /**
     * 線程池?zé)o法接收新任務(wù)時(shí),拒絕執(zhí)行任務(wù)處理器种柑,可以自定義
     */
    private volatile RejectedExecutionHandler handler;


    /**
     * work線程(非核心線程)空閑的時(shí)間岗仑,大于此時(shí)間是被銷毀
     */
    private volatile long keepAliveTime;


    /**
     * 是否允許回收核心work線程
     */
    private volatile boolean allowCoreThreadTimeOut;


    /**
     * 線程池中核心work線程的數(shù)量。
     */
    private volatile int corePoolSize;


    /**
     * 線程池中允許的最大work數(shù)量
     */
    private volatile int maximumPoolSize;


    private static final RejectedExecutionHandler defaultHandler =
            new AbortPolicy();


    private static final RuntimePermission shutdownPerm =
            new RuntimePermission("modifyThread");


    /**
     * work使用AQS同步鎖,用來(lái)判斷當(dāng)前work能否接收新任務(wù)
     *
     * 同步狀態(tài)0聚请,表示空閑 可以接收新任務(wù)
     * 同步狀態(tài)1荠雕,表示正在執(zhí)行任務(wù) 無(wú)法接收新任務(wù)
     *
     * 獲取同步狀態(tài)將 同步狀態(tài)設(shè)置為1 ,釋放同步狀態(tài)設(shè)置為0
     */
    private final class Worker
            extends AbstractQueuedSynchronizer
            implements Runnable
    {

        private static final long serialVersionUID = 6138294804551838833L;

        /** 工作線程*/
        final Thread thread;
        /** 初始化Worker驶赏,分配的第一個(gè)任務(wù) */
        Runnable firstTask;
        /** 每個(gè)work執(zhí)行的任務(wù)數(shù)量 */
        volatile long completedTasks;

        /**
         * 實(shí)例化Worker
         */
        Worker(Runnable firstTask) {
            setState(-1);
            this.firstTask = firstTask;
            this.thread = getThreadFactory().newThread(this);
        }

        /** 工作線程執(zhí)行炸卑,調(diào)用外部TheadPoolExecutor.runWorker方法  */
        public void run() {
            runWorker(this);
        }


        /**
         * 判斷當(dāng)前Work是否空閑
         */
        protected boolean isHeldExclusively() {
            return getState() != 0;
        }

        /**
         * tryAcquire 為AQS 嘗試獲取獨(dú)占同步狀態(tài)模板方法實(shí)現(xiàn)。
         */
        protected boolean tryAcquire(int unused) {

            if (compareAndSetState(0, 1)) {
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }

        /**
         * tryRelease為AQS 嘗試釋放獨(dú)占同步狀態(tài)模板方法實(shí)現(xiàn)煤傍。
         */
        protected boolean tryRelease(int unused) {
            setExclusiveOwnerThread(null);
            setState(0);
            return true;
        }

        /**
         * 獲取獨(dú)占同步狀態(tài)
         */
        public void lock()        { acquire(1); }

        /**
         * 嘗試獲取同步狀態(tài)
         */
        public boolean tryLock()  { return tryAcquire(1); }

        /**
         * 釋放獨(dú)占同步狀態(tài)
         */
        public void unlock()      { release(1); }

        /**
         * 判斷能夠護(hù)球同步狀態(tài)
         */
        public boolean isLocked() { return isHeldExclusively(); }

        /**
         * 中斷work正在執(zhí)行任務(wù)
         */
        void interruptIfStarted() {
            Thread t;
            if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
                try {
                    t.interrupt();
                } catch (SecurityException ignore) {
                }
            }
        }
    }



    /**
     * CAS+循環(huán)設(shè)置線程池狀態(tài)為shutdown
     */
    private void advanceRunState(int targetState) {
        for (;;) {
            int c = ctl.get();
            if (runStateAtLeast(c, targetState) ||
                    ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))
                break;
        }
    }

    /**
     * 嘗試將線程池狀態(tài)設(shè)置為Terminate
     */
    final void tryTerminate() {
        for (;;) {
            int c = ctl.get();
            /**
             * 判斷線程池能否進(jìn)入TERMINATED狀態(tài)
             * 如果以下3中情況任一為true盖文,return,不進(jìn)行終止
             * 1蚯姆、還在運(yùn)行狀態(tài)
             * 2五续、狀態(tài)是TIDYING、或 TERMINATED龄恋,已經(jīng)終止過(guò)了
             * 3疙驾、SHUTDOWN 且 workQueue不為空
             * 4
             */
            if (isRunning(c) ||
                    runStateAtLeast(c, TIDYING) ||
                    (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
                return;

            /** 線程池workQueue不為空 return,并中斷workQueue其中一個(gè)work**/

            /**
             * 線程池為stop狀態(tài)郭毕,且還存在work,中斷喚醒一個(gè)正在等任務(wù)的空閑worker它碎,
             * 再次調(diào)用getTask(),線程池狀態(tài)發(fā)生改變,返回null,work工作線程退出循環(huán)
             */
            if (workerCountOf(c) != 0) { // Eligible to terminate
                interruptIdleWorkers(ONLY_ONE);
                return;
            }
            /** 獲取主鎖:mainLock **/
            final ReentrantLock mainLock = this.mainLock;
            /** 加鎖 **/
            mainLock.lock();
            try {
                /** 將線程池狀態(tài)設(shè)置為TIDYING **/
                if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
                    try {
                        /** 釋放子類實(shí)現(xiàn) **/
                        terminated();
                    } finally {
                        /** 將線程池狀態(tài)設(shè)置為TERMINATED **/
                        ctl.set(ctlOf(TERMINATED, 0));
                        /** 釋放鎖 **/
                        termination.signalAll();
                    }
                    return;
                }
            } finally {
                /** 釋放鎖 **/
                mainLock.unlock();
            }
            // else retry on failed CAS
        }
    }

    /*
     * Methods for controlling interrupts to worker threads.
     */

    /**
     * 檢查調(diào)用者是否有權(quán)限shutdown線程池
     */
    private void checkShutdownAccess() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkPermission(shutdownPerm);
            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                for (Worker w : workers)
                    security.checkAccess(w.thread);
            } finally {
                mainLock.unlock();
            }
        }
    }

    /**
     * Interrupts all threads, even if active. Ignores SecurityExceptions
     * (in which case some threads may remain uninterrupted).
     */
    private void interruptWorkers() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            for (Worker w : workers)
                w.interruptIfStarted();
        } finally {
            mainLock.unlock();
        }
    }

    /**
     * 找到斷線程池中空閑的work,中斷其工作線程
     * onlyOne=true 表示僅僅中斷一個(gè)空閑的work
     * onlyOne=false 表示中斷所有空閑的work
     */
    private void interruptIdleWorkers(boolean onlyOne) {
        /** 獲取主鎖:mainLock **/
        final ReentrantLock mainLock = this.mainLock;
        /** 獲取鎖 **/
        mainLock.lock();
        try {
            /** 遍歷所有work **/
            for (Worker w : workers) {
                Thread t = w.thread;
                /** 判斷work工作線程是否沒(méi)有被中斷扳肛,且能獲取獨(dú)占同步狀態(tài)(空閑) **/
                if (!t.isInterrupted() && w.tryLock()) {
                    try {
                        /**  中斷work工作線程 **/
                        t.interrupt();
                    } catch (SecurityException ignore) {
                    } finally {
                        w.unlock();
                    }
                }
                if (onlyOne)
                    break;
            }
        } finally {
            /** 釋放鎖 **/
            mainLock.unlock();
        }
    }

    /**
     * 找到斷線程池中空閑的work傻挂,中斷其工作線程
     */
    private void interruptIdleWorkers() {
        interruptIdleWorkers(false);
    }

    private static final boolean ONLY_ONE = true;



    /**
     * 調(diào)用handler拒絕策略
     */
    final void reject(Runnable command) {
        //handler.rejectedExecution(command, this);
    }

    /**
     * 調(diào)用shutdown時(shí)運(yùn)行狀態(tài)轉(zhuǎn)換后執(zhí)行最后一步的清理模板方法
     */
    void onShutdown() {
    }

    /**
     * 判斷線程池狀態(tài)是RUNNING或SHUTDOWN,默認(rèn)僅狀態(tài)為RUNNING返回true
     * @param shutdownOK ==tue 時(shí) 狀態(tài)為SHUTDOWN也返回true
     */
    final boolean isRunningOrShutdown(boolean shutdownOK) {
        int rs = runStateOf(ctl.get());
        return rs == RUNNING || (rs == SHUTDOWN && shutdownOK);
    }

    /**
     * 將workQueue中的元素放入一個(gè)List并返回
     */
    private List<Runnable> drainQueue() {
        BlockingQueue<Runnable> q = workQueue;
        ArrayList<Runnable> taskList = new ArrayList<Runnable>();
        /** 將隊(duì)列中的值全部從隊(duì)列中移除,并賦值給對(duì)應(yīng)集合 **/
        q.drainTo(taskList);
        /** 并發(fā)在判斷 workQueue是否為空挖息,將新添加加入到taskList**/
        if (!q.isEmpty()) {
            for (Runnable r : q.toArray(new Runnable[0])) {
                if (q.remove(r))
                    taskList.add(r);
            }
        }
        return taskList;
    }

    /**
     * 創(chuàng)建一個(gè)work執(zhí)行任務(wù)
     * @param firstTask 任務(wù)(可以分配一個(gè)null,僅僅創(chuàng)建一個(gè)work)
     * @param core      是否創(chuàng)建的是一個(gè)core work
     * @return
     */
    private boolean addWorker(Runnable firstTask, boolean core) {
        retry:
        /** 無(wú)需循環(huán)校驗(yàn)金拒,成功推出  **/
        for (;;) {
            int c = ctl.get();
            int rs = runStateOf(c);

            /**
             * 校驗(yàn)?zāi)芊駝?chuàng)建一個(gè)work
             * rs > SHUTDOWN情況下,線程池狀態(tài)處于 旋讹,STOP殖蚕、TIDYING、TERMINATED狀態(tài)都不接收新任務(wù) 退出
             *
             * 當(dāng)rs == SHUTDOWN 需要 firstTask == null && 沉迹!workQueue.isEmpty() 表示創(chuàng)建一個(gè)work執(zhí)行空任務(wù)。就是去執(zhí)行任務(wù)隊(duì)列任務(wù)可以通過(guò)校驗(yàn)
             * 其他情況 退出
             *
             * **/
            if (rs >= SHUTDOWN &&
                    ! (rs == SHUTDOWN &&
                            firstTask == null &&
                            ! workQueue.isEmpty()))
                return false;

            /** 使用CASwork數(shù)量+1 **/
            for (;;) {
                /** 獲取當(dāng)前work數(shù)量 **/
                int wc = workerCountOf(c);

                /** 核心work數(shù)量大于corePoolSize害驹,總work大于maximumPoolSize直接返回 **/
                if (wc >= CAPACITY ||
                        wc >= (core ? corePoolSize : maximumPoolSize))
                    return false;

                /** worker + 1,成功跳出retry循環(huán) **/
                if (compareAndIncrementWorkerCount(c))
                    break retry;
                c = ctl.get();
                /** 如果狀態(tài)不等于之前獲取的state鞭呕,跳出內(nèi)層循環(huán),繼續(xù)去外層循環(huán)判斷 **/
                if (runStateOf(c) != rs)
                    continue retry;
                // else CAS failed due to workerCount change; retry inner loop
            }
        }

        /** 創(chuàng)建work并執(zhí)行任務(wù) **/
        boolean workerStarted = false;
        boolean workerAdded = false;
        Worker w = null;
        try {
            /** 實(shí)例化:Worker宛官,并分配任務(wù)firstTask **/
            w = new Worker(firstTask);
            final Thread t = w.thread;
            /** work中工作線程不為null **/
            if (t != null) {
                /** 獲取主鎖:mainLock **/
                final ReentrantLock mainLock = this.mainLock;
                /** 加鎖  **/
                mainLock.lock();
                try {
                    /** 獲取當(dāng)前線程池狀態(tài) **/
                    int rs = runStateOf(ctl.get());

                    /** 當(dāng)前線程池狀態(tài)為運(yùn)行葫松,或當(dāng)前線程池狀態(tài)為SHUTDOWN,提交是null任務(wù)
                     *  將創(chuàng)建的work添加到workers集合中
                     * **/
                    if (rs < SHUTDOWN ||
                            (rs == SHUTDOWN && firstTask == null)) {
                        if (t.isAlive()) // precheck that t is startable
                            throw new IllegalThreadStateException();
                        workers.add(w);
                        int s = workers.size();
                        if (s > largestPoolSize)
                            largestPoolSize = s;
                        workerAdded = true;
                    }
                } finally {
                    /** 釋放鎖  **/
                    mainLock.unlock();
                }
                /** 創(chuàng)建成功底洗,啟動(dòng)work執(zhí)行任務(wù) **/
                if (workerAdded) {
                    /** 啟動(dòng)work **/
                    t.start();
                    workerStarted = true;
                }
            }
        } finally {
            if (! workerStarted)
                /** 失敗創(chuàng)建work只能當(dāng)前線程池狀態(tài)不是運(yùn)行狀態(tài) **/
                addWorkerFailed(w);
        }
        return workerStarted;
    }

    /**
     * 失敗創(chuàng)建work只能當(dāng)前線程池狀態(tài)不是運(yùn)行狀態(tài)
     */
    private void addWorkerFailed(Worker w) {
        /** 獲取主鎖:mainLock **/
        final ReentrantLock mainLock = this.mainLock;
        /** 加鎖 **/
        mainLock.lock();
        try {
            /** 嘗試從workers刪除腋么,感覺(jué)沒(méi)啥用, **/
            if (w != null)
                workers.remove(w);
            /** 將work數(shù)量-1 **/
            decrementWorkerCount();
            /** 嘗試將線程池狀態(tài)設(shè)置為Terminate **/
            tryTerminate();
        } finally {
            /** 釋放 **/
            mainLock.unlock();
        }
    }

    /**
     * 執(zhí)行work銷毀退出操作
     * work 要結(jié)束的worker
     * completedAbruptly 表示是否需要對(duì)work數(shù)量-1操作
     *  runWorker 正常執(zhí)行時(shí) completedAbruptly 為false
     *  runWorker 執(zhí)行出現(xiàn)異常 completedAbruptly 為true
     */
    private void processWorkerExit(Worker w, boolean completedAbruptly) {
        if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
            decrementWorkerCount();

        /** 從workers 集合中移除worker **/
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            completedTaskCount += w.completedTasks;
            workers.remove(w);
        } finally {
            mainLock.unlock();
        }

        /** 嘗試將線程池狀態(tài)設(shè)置為Terminate **/
        tryTerminate();

        int c = ctl.get();
        /**  **/
        if (runStateLessThan(c, STOP)) {
            /** 如果 work正常退出亥揖,需要判斷當(dāng)前線程數(shù)量 < 要維護(hù)的線程數(shù)量 如果是addWorker()添加一個(gè)非核心work **/
            if (!completedAbruptly) {
                /**
                 * 如果允許回收核心線程珊擂,且workQueue還存在需要處理任務(wù) work線程需要大于1
                 * 如果不允許回收核心線程,則work線程需要大于corePoolSize
                 * **/
                int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
                if (min == 0 && ! workQueue.isEmpty())
                    min = 1;
                if (workerCountOf(c) >= min)
                    return; // replacement not needed
            }
            /** 如果 work 是異常退出  addWorker() 添加一個(gè)非核心work**/
            addWorker(null, false);
        }
    }

    /**
     * 從WorkQueue獲取任務(wù)
     * 同時(shí)用來(lái)判斷work何時(shí)退出銷毀
     */
    private Runnable getTask() {
        boolean timedOut = false; // Did the last poll() time out?

        /** 無(wú)限循環(huán)费变,
         *  當(dāng)work超過(guò)指定時(shí)間沒(méi)有獲取時(shí)摧扇,設(shè)置timedOut = true進(jìn)行二次遍歷時(shí)銷毀當(dāng)前work **/
        for (;;) {
            int c = ctl.get();
            int rs = runStateOf(c);

            /** 線程池中狀態(tài) >= STOP 或者 線程池狀態(tài) == SHUTDOWN且阻塞隊(duì)列為空,則停止worker - 1挚歧,return null **/
            if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
                decrementWorkerCount();
                return null;
            }

            /** 獲取work數(shù)量 **/
            int wc = workerCountOf(c);

            /**  判斷是否需要開(kāi)啟work淘汰機(jī)制 **/
            boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;


            /**
             * 以下幾種情況直接銷毀當(dāng)前work
             *
             * 超時(shí)沒(méi)有獲取任務(wù)timedOut=tue,for循環(huán)遍歷第二次時(shí)
             * 當(dāng)前任務(wù)超過(guò)maximumPoolSize
             * **/
            if ((wc > maximumPoolSize || (timed && timedOut))
                    && (wc > 1 || workQueue.isEmpty())) {
                if (compareAndDecrementWorkerCount(c))
                    return null;
                continue;
            }

            try {
                /**
                 * 如果開(kāi)啟work淘汰機(jī)制超時(shí)獲取任務(wù)扛稽,調(diào)用poll阻塞獲取任務(wù),存在超時(shí)滑负,如果超時(shí)沒(méi)有獲取到任務(wù)
                 * 設(shè)置timedOut = true 進(jìn)入第二次循環(huán)銷毀
                 *
                 * 如果沒(méi)開(kāi)啟work淘汰機(jī)制超時(shí)獲取任務(wù)在张,調(diào)用take阻塞獲取任務(wù)
                 * 【這里的阻塞都能被中斷響應(yīng)!矮慕!】
                 **/
                Runnable r = timed ?
                        workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                        workQueue.take();
                if (r != null)
                    return r;
                timedOut = true;
            } catch (InterruptedException retry) {
                timedOut = false;
            }
        }
    }


    /**
     * work執(zhí)行邏輯帮匾。
     * 內(nèi)部存在一個(gè)for循環(huán),不斷循環(huán)獲取任務(wù)執(zhí)行凡傅。當(dāng)線程池狀態(tài)還在運(yùn)行辟狈,work線程會(huì)一直運(yùn)行不會(huì)推出循環(huán)
     * getTask()線程返回null時(shí)退出,一般可能當(dāng)前work超時(shí)被銷毀或線程池不在運(yùn)行。
     * @param w
     */
    final void runWorker(Worker w) {
        /** 獲取當(dāng)前線程 **/
        Thread wt = Thread.currentThread();
        /** 獲取執(zhí)行任務(wù)**/
        Runnable task = w.firstTask;
        /** 將任務(wù)從work清理**/
        w.firstTask = null;
        /** 初始化同步狀態(tài)為0(創(chuàng)建時(shí)為-1) **/
        w.unlock(); // allow interrupts
        boolean completedAbruptly = true;
        try {
            /**
             * 如果當(dāng)前work中存在任務(wù)則執(zhí)行哼转,不存在則從WorkQueue獲取任務(wù)
             * getTask()明未!=null 時(shí)work永遠(yuǎn)不停止
             *  **/
            while (task != null || (task = getTask()) != null) {
                /** 獲取work獨(dú)占同步狀態(tài) **/
                w.lock();

                               /** 如果當(dāng)前線程池的狀態(tài)為STOP,將work中工作線程標(biāo)記為中斷
                 * 1壹蔓、如果線程池狀態(tài)>=stop趟妥,且當(dāng)前線程沒(méi)有設(shè)置中斷狀態(tài),wt.interrupt()
                 2佣蓉、如果一開(kāi)始判斷線程池狀態(tài)<stop披摄,但Thread.interrupted()為true,即線程已經(jīng)被中斷勇凭,又清除了中斷標(biāo)示疚膊,再次判斷線程池狀態(tài)是否>=stop
                 是,再次設(shè)置中斷標(biāo)示虾标,wt.interrupt()
                 *    否寓盗,不做操作,清除中斷標(biāo)示后進(jìn)行后續(xù)步驟
                 *
                 * **/
                if ((runStateAtLeast(ctl.get(), STOP) ||
                        (Thread.interrupted() &&
                                runStateAtLeast(ctl.get(), STOP))) &&
                        !wt.isInterrupted())
                    wt.interrupt();


                try {
                    /** 模板方法給子類擴(kuò)展 **/
                    beforeExecute(wt, task);
                    Throwable thrown = null;
                    try {
                        /** 處理任務(wù) **/
                        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 {
                        /** 模板方法給子類擴(kuò)展 **/
                        afterExecute(task, thrown);
                    }
                } finally {
                    /** 重置任務(wù) **/
                    task = null;
                    /** work執(zhí)行的任務(wù)數(shù)量  **/
                    w.completedTasks++;
                    /** 釋放work獨(dú)占同步狀態(tài) **/
                    w.unlock();
                }
            }
            completedAbruptly = false;
        } finally {
            processWorkerExit(w, completedAbruptly);
        }
    }


    /**
     * 創(chuàng)建一個(gè)線程池,使用默認(rèn)線程池的拒絕策略和創(chuàng)建work工廠
     * @param corePoolSize 線程池中核心work線程的數(shù)量璧函。
     * @param maximumPoolSize 線程池中允許的最大work數(shù)量
     * @param keepAliveTime work線程(非核心線程)空閑的時(shí)間傀蚌,大于此時(shí)間是被銷毀
     * @param unit keepAliveTime的單位。TimeUnit
     * @param workQueue 用來(lái)保存等待執(zhí)行的任務(wù)的阻塞隊(duì)列
     */
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
                Executors.defaultThreadFactory(), defaultHandler);
    }

    /**
     * 創(chuàng)建一個(gè)線程池,使用默認(rèn)線程池的拒絕策略
     * @param corePoolSize 線程池中核心work線程的數(shù)量蘸吓。
     * @param maximumPoolSize 線程池中允許的最大work數(shù)量
     * @param keepAliveTime work線程(非核心線程)空閑的時(shí)間善炫,大于此時(shí)間是被銷毀
     * @param unit keepAliveTime的單位。TimeUnit
     * @param workQueue 用來(lái)保存等待執(zhí)行的任務(wù)的阻塞隊(duì)列
     * @param threadFactory 創(chuàng)建work工廠
     */
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
                threadFactory, defaultHandler);
    }

    /**
     * 創(chuàng)建一個(gè)線程池,使用默認(rèn)的創(chuàng)建work工廠
     * @param corePoolSize 線程池中核心work線程的數(shù)量库继。
     * @param maximumPoolSize 線程池中允許的最大work數(shù)量
     * @param keepAliveTime work線程(非核心線程)空閑的時(shí)間箩艺,大于此時(shí)間是被銷毀
     * @param unit keepAliveTime的單位。TimeUnit
     * @param workQueue 用來(lái)保存等待執(zhí)行的任務(wù)的阻塞隊(duì)列
     * @param 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);
    }

    /**
     * 創(chuàng)建一個(gè)線程池制跟,
     * @param corePoolSize 線程池中核心work線程的數(shù)量舅桩。
     * @param maximumPoolSize 線程池中允許的最大work數(shù)量
     * @param keepAliveTime work線程(非核心線程)空閑的時(shí)間,大于此時(shí)間是被銷毀
     * @param unit keepAliveTime的單位雨膨。TimeUnit
     * @param workQueue 用來(lái)保存等待執(zhí)行的任務(wù)的阻塞隊(duì)列
     * @param threadFactory 創(chuàng)建work工廠
     * @param 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;
    }


    /**
     * 執(zhí)行任務(wù)
     */
    public void execute(Runnable command) {
        /** 提交任務(wù)為null 拋出異常擂涛。 **/
        if (command == null)
            throw new NullPointerException();

        /** 獲取ctl **/
        int c = ctl.get();

        /** work線程數(shù)量少于corePoolSize **/
        if (workerCountOf(c) < corePoolSize) {
            /** 創(chuàng)建新work線程并設(shè)置為核心線程執(zhí)行任務(wù) addWorker(command, true)  **/
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        /** 進(jìn)入此邏輯表示work線程數(shù)量大于corePoolSize或者前一步執(zhí)行失敗 **/

        /** 判斷線程池是Running運(yùn)行狀態(tài),將任務(wù)添加到workQueue尾部成功(隊(duì)列滿了返回false) **/
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            /** Double Check下當(dāng)前線程狀態(tài)是不是Running運(yùn)行狀態(tài)聊记,不是就刪除剛剛添加的任務(wù)撒妈,執(zhí)行拒絕任務(wù) **/
            if (! isRunning(recheck) && remove(command))
                reject(command);
            /** 異常情況 前面workerCountOf(c) < corePoolSize說(shuō)明當(dāng)時(shí)還存在大量work,說(shuō)明線程池突然停止排监,為保證任務(wù)都能處理狰右,
             * 創(chuàng)建一個(gè)臨時(shí)work去處理當(dāng)前workQueue中的任務(wù)  **/
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }

        /** 隊(duì)列滿了,創(chuàng)建一個(gè)非核心work執(zhí)行新添加任務(wù) **/
        else if (!addWorker(command, false))
             /** 執(zhí)行失敗舆床,執(zhí)行拒絕任務(wù) **/
            reject(command);
    }

    /**
     * 溫柔的終止線程池
     */
    public void shutdown() {
        /** 獲取主鎖:mainLock **/
        final ReentrantLock mainLock = this.mainLock;
        /** 加鎖 **/
        mainLock.lock();
        try {
            /** 判斷調(diào)用者是否有權(quán)限shutdown線程池 **/
            checkShutdownAccess();
            /** CAS+循環(huán)設(shè)置線程池狀態(tài)為shutdown  **/
            advanceRunState(SHUTDOWN);
            /** 找到斷線程池中空閑的work棋蚌,中斷其工作線程   **/
            interruptIdleWorkers();
            onShutdown(); // hook for ScheduledThreadPoolExecutor
        } finally {
            /** 釋放鎖 **/
            mainLock.unlock();
        }
        /** 嘗試將線程池狀態(tài)設(shè)置為Terminate **/
        tryTerminate();
    }

    /**
     * 強(qiáng)硬的終止線程池
     * 返回在隊(duì)列中沒(méi)有執(zhí)行的任務(wù)
     */
    public List<Runnable> shutdownNow() {
        List<Runnable> tasks;
        /** 獲取主鎖:mainLock **/
        final ReentrantLock mainLock = this.mainLock;
        /** 加鎖 **/
        mainLock.lock();
        try {
            /** 判斷調(diào)用者是否有權(quán)限shutdown線程池 **/
            checkShutdownAccess();
            /** CAS+循環(huán)設(shè)置線程池狀態(tài)為shutdown  **/
            advanceRunState(STOP);
            /** 找到斷線程池中空閑的work嫁佳,中斷其工作線程   **/
            interruptWorkers();
            tasks = drainQueue();
        } finally {
            /** 釋放鎖 **/
            mainLock.unlock();
        }
        /** 嘗試將線程池狀態(tài)設(shè)置為Terminate **/
        tryTerminate();
        return tasks;
    }

    /**
     * 判斷當(dāng)前線程池狀態(tài)是非運(yùn)行狀態(tài)
     */
    public boolean isShutdown() {
        return ! isRunning(ctl.get());
    }

    /**
     * 判斷線程池正在停止到TERMINATED狀態(tài)過(guò)程中
     */
    public boolean isTerminating() {
        int c = ctl.get();
        return ! isRunning(c) && runStateLessThan(c, TERMINATED);
    }

    /**
     * 返回線程池 狀態(tài)是否為TERMINATED
     */
    public boolean isTerminated() {
        return runStateAtLeast(ctl.get(), TERMINATED);
    }

    /**
     * 等待線程終止
     * @param timeout
     * @param unit
     * @return
     * @throws InterruptedException
     */
    public boolean awaitTermination(long timeout, TimeUnit unit)
            throws InterruptedException {
        /** 獲取等待時(shí)間 **/
        long nanos = unit.toNanos(timeout);
        /** 獲取主鎖:mainLock **/
        final ReentrantLock mainLock = this.mainLock;
        /** 加鎖 **/
        mainLock.lock();
        try {
            for (;;) {
                /**  當(dāng)線程狀態(tài)為終止時(shí)返回 **/
                if (runStateAtLeast(ctl.get(), TERMINATED))
                    return true;
                /** 超時(shí)返回 **/
                if (nanos <= 0)
                    return false;
                nanos = termination.awaitNanos(nanos);
            }
        } finally {
            /** 釋放鎖 **/
            mainLock.unlock();
        }
    }



    protected void finalize() {
        shutdown();
    }

    /**
     * 設(shè)置 threadFactory
     */
    public void setThreadFactory(ThreadFactory threadFactory) {
        if (threadFactory == null)
            throw new NullPointerException();
        this.threadFactory = threadFactory;
    }

    /**
     * 獲取 threadFactory
     */
    public ThreadFactory getThreadFactory() {
        return threadFactory;
    }

    /**
     * 設(shè)置 handler
     */
    public void setRejectedExecutionHandler(RejectedExecutionHandler handler) {
        if (handler == null)
            throw new NullPointerException();
        this.handler = handler;
    }

    /**
     * 獲取 handler
     */
    public RejectedExecutionHandler getRejectedExecutionHandler() {
        return handler;
    }

    /**
     * 設(shè)置corePoolSize
     */
    public void setCorePoolSize(int corePoolSize) {
        if (corePoolSize < 0)
            throw new IllegalArgumentException();
        int delta = corePoolSize - this.corePoolSize;
        this.corePoolSize = corePoolSize;
        if (workerCountOf(ctl.get()) > corePoolSize)
            interruptIdleWorkers();
        else if (delta > 0) {
            // We don't really know how many new threads are "needed".
            // As a heuristic, prestart enough new workers (up to new
            // core size) to handle the current number of tasks in
            // queue, but stop if queue becomes empty while doing so.
            int k = Math.min(delta, workQueue.size());
            while (k-- > 0 && addWorker(null, true)) {
                if (workQueue.isEmpty())
                    break;
            }
        }
    }

    /**
     * 返回corePoolSize
     */
    public int getCorePoolSize() {
        return corePoolSize;
    }

    /**
     * 如果線程池中work線程數(shù)量小于corePoolSize,添加一個(gè)核心work
     */
    public boolean prestartCoreThread() {
        return workerCountOf(ctl.get()) < corePoolSize &&
                addWorker(null, true);
    }

    /**
     * 添加一個(gè)work
     */
    void ensurePrestart() {
        int wc = workerCountOf(ctl.get());
        if (wc < corePoolSize)
            addWorker(null, true);
        else if (wc == 0)
            addWorker(null, false);
    }

    /**
     * 初始化添加核心work到corePoolSize
     */
    public int prestartAllCoreThreads() {
        int n = 0;
        while (addWorker(null, true))
            ++n;
        return n;
    }

    /**
     * 返回 allowCoreThreadTimeOut
     */
    public boolean allowsCoreThreadTimeOut() {
        return allowCoreThreadTimeOut;
    }

    /**
     * 設(shè)置 allowCoreThreadTimeOut 設(shè)置為true
     * 找到斷線程池中空閑的work谷暮,中斷其工作線程
     * @since 1.6
     */
    public void allowCoreThreadTimeOut(boolean value) {
        if (value && keepAliveTime <= 0)
            throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
        if (value != allowCoreThreadTimeOut) {
            allowCoreThreadTimeOut = value;
            if (value)
                interruptIdleWorkers();
        }
    }

    /**
     * 設(shè)置maximumPoolSize蒿往,如果設(shè)置maximumPoolSize大于原始值
     * 找到斷線程池中空閑的work,中斷其工作線程
     */
    public void setMaximumPoolSize(int maximumPoolSize) {
        if (maximumPoolSize <= 0 || maximumPoolSize < corePoolSize)
            throw new IllegalArgumentException();
        this.maximumPoolSize = maximumPoolSize;
        if (workerCountOf(ctl.get()) > maximumPoolSize)
            interruptIdleWorkers();
    }

    /**
     * 返回maximumPoolSize
     */
    public int getMaximumPoolSize() {
        return maximumPoolSize;
    }

    /**
     * 設(shè)置keepAliveTime湿弦,如果keepAliveTime小于原始值
     * 找到斷線程池中空閑的work瓤漏,中斷其工作線程
     */
    public void setKeepAliveTime(long time, TimeUnit unit) {
        if (time < 0)
            throw new IllegalArgumentException();
        if (time == 0 && allowsCoreThreadTimeOut())
            throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
        long keepAliveTime = unit.toNanos(time);
        long delta = keepAliveTime - this.keepAliveTime;
        this.keepAliveTime = keepAliveTime;
        if (delta < 0)
            interruptIdleWorkers();
    }

    /**
     * 返回 keepAliveTime
     */
    public long getKeepAliveTime(TimeUnit unit) {
        return unit.convert(keepAliveTime, TimeUnit.NANOSECONDS);
    }

    /* User-level queue utilities */

    /**
     * 返回workQueue
     */
    public BlockingQueue<Runnable> getQueue() {
        return workQueue;
    }

    /**
     * 從workQueue 刪除task
     */
    public boolean remove(Runnable task) {
        boolean removed = workQueue.remove(task);
        tryTerminate(); // In case SHUTDOWN and now empty
        return removed;
    }

    /**
     * 遍歷線程池所有work,將工作線程狀態(tài)為取消的刪除
     */
    public void purge() {
        final BlockingQueue<Runnable> q = workQueue;
        try {
            Iterator<Runnable> it = q.iterator();
            while (it.hasNext()) {
                Runnable r = it.next();
                if (r instanceof Future<?> && ((Future<?>)r).isCancelled())
                    it.remove();
            }
        } catch (ConcurrentModificationException fallThrough) {

            for (Object r : q.toArray())
                if (r instanceof Future<?> && ((Future<?>)r).isCancelled())
                    q.remove(r);
        }

        tryTerminate();
    }

    /* Statistics */

    /**
     * 獲取work數(shù)量
     */
    public int getPoolSize() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            return runStateAtLeast(ctl.get(), TIDYING) ? 0
                    : workers.size();
        } finally {
            mainLock.unlock();
        }
    }

    /**
     * 獲取正在執(zhí)行任務(wù)work
     */
    public int getActiveCount() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            int n = 0;
            for (Worker w : workers)
                if (w.isLocked())
                    ++n;
            return n;
        } finally {
            mainLock.unlock();
        }
    }

    /**
     * 獲取work數(shù)量
     */
    public int getLargestPoolSize() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            return largestPoolSize;
        } finally {
            mainLock.unlock();
        }
    }

    /**
     * 獲取待完成任務(wù)
     */
    public long getTaskCount() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            long n = completedTaskCount;
            for (Worker w : workers) {
                n += w.completedTasks;
                if (w.isLocked())
                    ++n;
            }
            return n + workQueue.size();
        } finally {
            mainLock.unlock();
        }
    }

    /**
     * 獲取線程池完成任務(wù)總理
     */
    public long getCompletedTaskCount() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            long n = completedTaskCount;
            for (Worker w : workers)
                n += w.completedTasks;
            return n;
        } finally {
            mainLock.unlock();
        }
    }

    /**
     * 線程池用字符串及表示
     */
    public String toString() {
        long ncompleted;
        int nworkers, nactive;
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            ncompleted = completedTaskCount;
            nactive = 0;
            nworkers = workers.size();
            for (Worker w : workers) {
                ncompleted += w.completedTasks;
                if (w.isLocked())
                    ++nactive;
            }
        } finally {
            mainLock.unlock();
        }
        int c = ctl.get();
        String rs = (runStateLessThan(c, SHUTDOWN) ? "Running" :
                (runStateAtLeast(c, TERMINATED) ? "Terminated" :
                        "Shutting down"));
        return super.toString() +
                "[" + rs +
                ", pool size = " + nworkers +
                ", active threads = " + nactive +
                ", queued tasks = " + workQueue.size() +
                ", completed tasks = " + ncompleted +
                "]";
    }

    /* Extension hooks */

    /**
     * 模板方法給子類實(shí)現(xiàn)颊埃,執(zhí)行任務(wù)前的操作
     */
    protected void beforeExecute(Thread t, Runnable r) { }

    /**
     * 模板方法給子類實(shí)現(xiàn)蔬充,執(zhí)行任務(wù)后的操作
     */
    protected void afterExecute(Runnable r, Throwable t) { }

    /**
     * 模板方法給子類實(shí)現(xiàn),線程池狀態(tài)從TIDYING到TERMINATED需要做的清理動(dòng)作
     */
    protected void terminated() { }

    /* Predefined RejectedExecutionHandlers */

    /**
     * A handler for rejected tasks that runs the rejected task
     * directly in the calling thread of the {@code execute} method,
     * unless the executor has been shut down, in which case the task
     * is discarded.
     */
    public static class CallerRunsPolicy implements RejectedExecutionHandler {
        /**
         * Creates a {@code CallerRunsPolicy}.
         */
        public CallerRunsPolicy() { }

        /**
         * Executes task r in the caller's thread, unless the executor
         * has been shut down, in which case the task is discarded.
         *
         * @param r the runnable task requested to be executed
         * @param e the executor attempting to execute this task
         */
        public void rejectedExecution(Runnable r, java.util.concurrent.ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                r.run();
            }
        }
    }

    /**
     * A handler for rejected tasks that throws a
     * {@code RejectedExecutionException}.
     */
    public static class AbortPolicy implements RejectedExecutionHandler {
        /**
         * Creates an {@code AbortPolicy}.
         */
        public AbortPolicy() { }

        /**
         * Always throws RejectedExecutionException.
         *
         * @param r the runnable task requested to be executed
         * @param e the executor attempting to execute this task
         * @throws RejectedExecutionException always
         */
        public void rejectedExecution(Runnable r, java.util.concurrent.ThreadPoolExecutor e) {
            throw new RejectedExecutionException("Task " + r.toString() +
                    " rejected from " +
                    e.toString());
        }
    }

    /**
     * A handler for rejected tasks that silently discards the
     * rejected task.
     */
    public static class DiscardPolicy implements RejectedExecutionHandler {
        /**
         * Creates a {@code DiscardPolicy}.
         */
        public DiscardPolicy() { }

        /**
         * Does nothing, which has the effect of discarding task r.
         *
         * @param r the runnable task requested to be executed
         * @param e the executor attempting to execute this task
         */
        public void rejectedExecution(Runnable r, java.util.concurrent.ThreadPoolExecutor e) {
        }
    }

    /**
     * A handler for rejected tasks that discards the oldest unhandled
     * request and then retries {@code execute}, unless the executor
     * is shut down, in which case the task is discarded.
     */
    public static class DiscardOldestPolicy implements RejectedExecutionHandler {
        /**
         * Creates a {@code DiscardOldestPolicy} for the given executor.
         */
        public DiscardOldestPolicy() { }

        /**
         * Obtains and ignores the next task that the executor
         * would otherwise execute, if one is immediately available,
         * and then retries execution of task r, unless the executor
         * is shut down, in which case task r is instead discarded.
         *
         * @param r the runnable task requested to be executed
         * @param e the executor attempting to execute this task
         */
        public void rejectedExecution(Runnable r, java.util.concurrent.ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                e.getQueue().poll();
                e.execute(r);
            }
        }
    }
}


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末班利,一起剝皮案震驚了整個(gè)濱河市饥漫,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌罗标,老刑警劉巖趾浅,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異馒稍,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)浅侨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門纽谒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人如输,你說(shuō)我怎么就攤上這事鼓黔。” “怎么了不见?”我有些...
    開(kāi)封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵澳化,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我稳吮,道長(zhǎng)缎谷,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任灶似,我火速辦了婚禮列林,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘酪惭。我一直安慰自己希痴,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布春感。 她就那樣靜靜地躺著砌创,像睡著了一般虏缸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上嫩实,一...
    開(kāi)封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天刽辙,我揣著相機(jī)與錄音,去河邊找鬼舶赔。 笑死扫倡,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的竟纳。 我是一名探鬼主播撵溃,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼锥累!你這毒婦竟也來(lái)了缘挑?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤桶略,失蹤者是張志新(化名)和其女友劉穎语淘,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體际歼,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡惶翻,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鹅心。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吕粗。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖旭愧,靈堂內(nèi)的尸體忽然破棺而出颅筋,到底是詐尸還是另有隱情,我是刑警寧澤输枯,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布议泵,位于F島的核電站,受9級(jí)特大地震影響桃熄,放射性物質(zhì)發(fā)生泄漏先口。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一蜻拨、第九天 我趴在偏房一處隱蔽的房頂上張望池充。 院中可真熱鬧,春花似錦缎讼、人聲如沸收夸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)卧惜。三九已至厘灼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間咽瓷,已是汗流浹背设凹。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留茅姜,地道東北人闪朱。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像钻洒,于是被迫代替她去往敵國(guó)和親奋姿。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容