Android 對(duì)于線程呻粹,線程池的操作

說(shuō)到線程就要說(shuō)說(shuō)線程機(jī)制 Handler,Looper,MessageQueue 可以說(shuō)是三座大山了

Handler

Handler 其實(shí)就是一個(gè)處理者,或者說(shuō)一個(gè)發(fā)送者,它會(huì)把消息發(fā)送給消息隊(duì)列贵扰,也就是Looper,然后在一個(gè)無(wú)限循環(huán)隊(duì)列中進(jìn)行取出消息的操作 mMyHandler.sendMessage(mMessage); 這句話就是我耗時(shí)操作處理完了流部,我發(fā)送過(guò)去了! 然后在接受的地方處理戚绕!簡(jiǎn)單理解是不是很簡(jiǎn)單。

一般我們?cè)陧?xiàng)目中異步操作都是怎么做的呢枝冀?
    // 這里開(kāi)啟一個(gè)子線程進(jìn)行耗時(shí)操作
    new Thread() {
        @Override
        public void run() {
            .......
            Message mMessage = new Message();
            mMessage.what = 1;
            //在這里發(fā)送給消息隊(duì)列
            mMyHandler.sendMessage(mMessage);
            }
        }.start();
    /**
     * 這里就是處理的地方 通過(guò)msg.what進(jìn)行處理分辨
     */
    class MyHandler extends Handler{
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
            //取出對(duì)應(yīng)的消息進(jìn)行處理
                ........
            }
        }
    }
    

那么我們的消息隊(duì)列是在什么地方啟動(dòng)的呢?跟隨源碼看一看

# ActivityThread.main
public static void main(String[] args) {
        //省略代碼舞丛。。果漾。球切。。
        
        //在這里創(chuàng)建了一個(gè)消息隊(duì)列绒障!
        Looper.prepareMainLooper();

        ActivityThread thread = new ActivityThread();
        thread.attach(false);

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        //這句我也沒(méi)有看懂 這不是一直都不會(huì)執(zhí)行的么
        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        //消息隊(duì)列跑起來(lái)了吨凑!
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
    public Handler(Callback callback, boolean async) {
        mLooper = Looper.myLooper();
        //注意看這里拋出的異常 如果這里mLooper==null
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread that has not called Looper.prepare()");
        }
        //獲取消息隊(duì)列
        mQueue = mLooper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }

以上操作Android系統(tǒng)就獲取并且啟動(dòng)了一個(gè)消息隊(duì)列,過(guò)多的源碼這里不想去描述户辱,免的占用很多篇幅

這里說(shuō)一下面試常見(jiàn)的一個(gè)問(wèn)題鸵钝,就是在子線程中可不可以創(chuàng)建一個(gè)Handler,其實(shí)是可以的庐镐,但是誰(shuí)這么用啊- -

    new Thread() {
        Handler mHandler = null;
        @Override
        public void run() {
            //在這里獲取
            Looper.prepare();
            mHandler = new Handler();
            //在這里啟動(dòng)
            Looper.loop();
        }
    }.start();

多線程的創(chuàng)建

一般我們?cè)陂_(kāi)發(fā)過(guò)程中要開(kāi)啟一個(gè)線程都是直接

        new Thread() {
            @Override
            public void run() {
                doing.....
            }
        }.start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                doing.....
            }
        }).start();

注意看恩商,一個(gè)傳遞了Runnable對(duì)象,另一個(gè)沒(méi)有,但是這兩個(gè)有什么不同焚鹊,為什么要衍生出2個(gè)呢痕届?
這里不去看源碼,簡(jiǎn)單敘述一下末患,實(shí)際上Thread是Runnabled的一個(gè)包裝實(shí)現(xiàn)類研叫,Runnable只有一個(gè)方法,就是run(),在這里以前也想過(guò)璧针,為什么Runnable只有一個(gè)方法呢嚷炉,后來(lái)的某一次交談中也算是找到一個(gè)答案,可能是因?yàn)槎嗤卣固匠鳎赡躂AVA語(yǔ)言想拓展一些其他的東西申屹,以后就直接在Runnable再寫(xiě)了绘证。不然我是沒(méi)有想到另一答案為什么都要傳遞一個(gè)Runnable,可能就像我們開(kāi)發(fā)中的baseActivity一樣吧


線程常用的操作方法

  • wait() 當(dāng)一個(gè)線程執(zhí)行到了wait() 就會(huì)進(jìn)去一個(gè)和對(duì)象有關(guān)的等待池中,同時(shí)失去了釋放當(dāng)前對(duì)象的機(jī)所哗讥,使其他線程可以訪問(wèn)嚷那,也就是讓其他線程可以調(diào)用notify()喚醒
  • sleep() 調(diào)用得線程進(jìn)入睡眠狀態(tài),不能該改變對(duì)象的機(jī)鎖杆煞,其他線程不能訪問(wèn)
  • join() 就等自己完事
  • yidld 你急你先來(lái)

簡(jiǎn)單的白話敘述其實(shí)也就是這樣魏宽,希望能看看demo然后理解一下。


一些其他的方法决乎,Callable,Future,FutureTask

Runnable是線程管理的拓展接口队询,不可以運(yùn)用于線程池,所以你總要有方法可以在線程池中管理啊所以Callable,Future,FutureTask就是可以在線程池中開(kāi)啟線程的接口。

Future定義了規(guī)范的接口构诚,如get(),isDone(),isCancelled()...FutureTask是他的實(shí)現(xiàn)類這里簡(jiǎn)單說(shuō)一下他的用法

/**
 * ================================================
 * 作    者:夏沐堯  Github地址:https://github.com/XiaMuYaoDQX
 * 版    本:1.0
 * 創(chuàng)建日期: 2018/1/10
 * 描    述:
 * 修訂歷史:
 * ================================================
 */
class FutureDemo {
    //創(chuàng)建一個(gè)單例線程
    static ExecutorService mExecutor = Executors.newSingleThreadScheduledExecutor();

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ftureWithRunnable();
        ftureWithCallable();
        ftureTask();
    }

    /**
     * 沒(méi)有指定返回值蚌斩,所以返回的是null,向線程池中提交的是Runnable
     *
     * @throws ExecutionException
     * @throws InterruptedException
     */
    private static void ftureWithRunnable() throws ExecutionException, InterruptedException {
        Future<?> result1 = mExecutor.submit(new Runnable() {
            @Override
            public void run() {
                fibc(20);
                System.out.println(Thread.currentThread().getName());
            }
        });
        System.out.println("Runnable" + result1.get());
    }

    /**
     * 提交了Callable,有返回值范嘱,可以獲取阻塞線程獲取到數(shù)值
     *
     * @throws ExecutionException
     * @throws InterruptedException
     */
    private static void ftureWithCallable() throws ExecutionException, InterruptedException {
        Future<Integer> result2 = mExecutor.submit(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                System.out.println(Thread.currentThread().getName());
                return fibc(20);
            }
        });
        System.out.println("Callable" + result2.get());
    }

    /**
     * 提交的futureTask對(duì)象
     * @throws ExecutionException
     * @throws InterruptedException
     */
    private static void ftureTask() throws ExecutionException, InterruptedException {
        FutureTask<Integer> futureTask = new FutureTask<Integer>(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                System.out.println(Thread.currentThread().getName());
                return fibc(20);
            }
        });
        mExecutor.submit(futureTask);
        System.out.println("futureTask" + futureTask.get());

    }

    private static int fibc(int num) {
        if (num == 0) {
            return 0;
        }
        if (num == 1) {
            return 1;
        }
        return fibc(num - 1) + fibc(num - 2);
    }
}

線程池

Java通過(guò)Executors提供線程池送膳,分別為:

  • newCachedThreadPool創(chuàng)建一個(gè)可緩存線程池,如果線程池長(zhǎng)度超過(guò)處理需要丑蛤,可靈活回收空閑線程肠缨,若無(wú)可回收,則新建線程盏阶。
  • newFixedThreadPool 創(chuàng)建一個(gè)定長(zhǎng)線程池,可控制線程最大并發(fā)數(shù)闻书,超出的線程會(huì)在隊(duì)列中等待名斟。
  • newScheduledThreadPool 創(chuàng)建一個(gè)定長(zhǎng)線程池,支持定時(shí)及周期性任務(wù)執(zhí)行魄眉。
  • newSingleThreadExecutor 創(chuàng)建一個(gè)單線程化的線程池砰盐,它只會(huì)用唯一的工作線程來(lái)執(zhí)行任務(wù),保證所有任務(wù)按照指定順序(FIFO, LIFO, 優(yōu)先級(jí))執(zhí)行坑律。

示例代碼

  • newCachedThreadPool
    創(chuàng)建一個(gè)可緩存線程池岩梳,如果線程池長(zhǎng)度超過(guò)處理需要,可靈活回收空閑線程晃择,若無(wú)可回收冀值,則新建線程。示例代碼如下:
public class ThreadPoolExecutorTest {  
 public static void main(String[] args) {  
  ExecutorService cachedThreadPool = Executors.newCachedThreadPool();  
  for (int i = 0; i < 10; i++) {  
   final int index = i;  
   try {  
    Thread.sleep(index * 1000);  
   } catch (InterruptedException e) {  
    e.printStackTrace();  
   }  
   cachedThreadPool.execute(new Runnable() {  
    public void run() {  
     System.out.println(index);  
    }  
   });  
  }  
 }  
} 
線程池為無(wú)限大宫屠,當(dāng)執(zhí)行第二個(gè)任務(wù)時(shí)第一個(gè)任務(wù)已經(jīng)完成列疗,會(huì)復(fù)用執(zhí)行第一個(gè)任務(wù)的線程,而不用每次新建線程浪蹂。
  • newFixedThreadPool
    創(chuàng)建一個(gè)定長(zhǎng)線程池抵栈,可控制線程最大并發(fā)數(shù)告材,超出的線程會(huì)在隊(duì)列中等待。示例代碼如下:
public class ThreadPoolExecutorTest {  
 public static void main(String[] args) {  
  ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);  
  for (int i = 0; i < 10; i++) {  
   final int index = i;  
   fixedThreadPool.execute(new Runnable() {  
    public void run() {  
     try {  
      System.out.println(index);  
      Thread.sleep(2000);  
     } catch (InterruptedException e) {  
      e.printStackTrace();  
     }  
    }  
   });  
  }  
 }  
}  
因?yàn)榫€程池大小為3古劲,每個(gè)任務(wù)輸出index后sleep 2秒斥赋,所以每?jī)擅氪蛴?個(gè)數(shù)字。
定長(zhǎng)線程池的大小最好根據(jù)系統(tǒng)資源進(jìn)行設(shè)置产艾。如Runtime.getRuntime().availableProcessors()
  • newScheduledThreadPool
    創(chuàng)建一個(gè)定長(zhǎng)線程池疤剑,支持定時(shí)及周期性任務(wù)執(zhí)行。延遲執(zhí)行示例代碼如下:
public class ThreadPoolExecutorTest {  
 public static void main(String[] args) {  
  ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);  
  scheduledThreadPool.schedule(new Runnable() {  
   public void run() {  
    System.out.println("delay 3 seconds");  
   }  
  }, 3, TimeUnit.SECONDS);  
 }  
}  
表示延遲3秒執(zhí)行胰舆。

定期執(zhí)行示例代碼如下:

public class ThreadPoolExecutorTest {  
 public static void main(String[] args) {  
  ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);  
  scheduledThreadPool.scheduleAtFixedRate(new Runnable() {  
   public void run() {  
    System.out.println("delay 1 seconds, and excute every 3 seconds");  
   }  
  }, 1, 3, TimeUnit.SECONDS);  
 }  
}  
表示延遲1秒后每3秒執(zhí)行一次骚露。
  • newSingleThreadExecutor
public class ThreadPoolExecutorTest {  
 public static void main(String[] args) {  
  ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();  
  for (int i = 0; i < 10; i++) {  
   final int index = i;  
   singleThreadExecutor.execute(new Runnable() {  
    public void run() {  
     try {  
      System.out.println(index);  
      Thread.sleep(2000);  
     } catch (InterruptedException e) {  
      e.printStackTrace();  
     }  
    }  
   });  
  }  
 }  
}  

這里只是簡(jiǎn)單敘述了一下線程的管理的各種方法,后續(xù)還會(huì)針對(duì)進(jìn)行講解
2018年1月17日下午8:19說(shuō)到線程就要說(shuō)說(shuō)線程機(jī)制 Handler,Looper,MessageQueue 可以說(shuō)是三座大山了

Handler

Handler 其實(shí)就是一個(gè)處理者,或者說(shuō)一個(gè)發(fā)送者缚窿,它會(huì)把消息發(fā)送給消息隊(duì)列棘幸,也就是Looper,然后在一個(gè)無(wú)限循環(huán)隊(duì)列中進(jìn)行取出消息的操作 mMyHandler.sendMessage(mMessage); 這句話就是我耗時(shí)操作處理完了倦零,我發(fā)送過(guò)去了! 然后在接受的地方處理误续!簡(jiǎn)單理解是不是很簡(jiǎn)單。

一般我們?cè)陧?xiàng)目中異步操作都是怎么做的呢扫茅?
    // 這里開(kāi)啟一個(gè)子線程進(jìn)行耗時(shí)操作
    new Thread() {
        @Override
        public void run() {
            .......
            Message mMessage = new Message();
            mMessage.what = 1;
            //在這里發(fā)送給消息隊(duì)列
            mMyHandler.sendMessage(mMessage);
            }
        }.start();
    /**
     * 這里就是處理的地方 通過(guò)msg.what進(jìn)行處理分辨
     */
    class MyHandler extends Handler{
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
            //取出對(duì)應(yīng)的消息進(jìn)行處理
                ........
            }
        }
    }
    

那么我們的消息隊(duì)列是在什么地方啟動(dòng)的呢?跟隨源碼看一看

# ActivityThread.main
public static void main(String[] args) {
        //省略代碼蹋嵌。。葫隙。栽烂。。
        
        //在這里創(chuàng)建了一個(gè)消息隊(duì)列恋脚!
        Looper.prepareMainLooper();

        ActivityThread thread = new ActivityThread();
        thread.attach(false);

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        //這句我也沒(méi)有看懂 這不是一直都不會(huì)執(zhí)行的么
        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        //消息隊(duì)列跑起來(lái)了腺办!
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
    public Handler(Callback callback, boolean async) {
        mLooper = Looper.myLooper();
        //注意看這里拋出的異常 如果這里mLooper==null
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread that has not called Looper.prepare()");
        }
        //獲取消息隊(duì)列
        mQueue = mLooper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }

以上操作Android系統(tǒng)就獲取并且啟動(dòng)了一個(gè)消息隊(duì)列,過(guò)多的源碼這里不想去描述糟描,免的占用很多篇幅

這里說(shuō)一下面試常見(jiàn)的一個(gè)問(wèn)題怀喉,就是在子線程中可不可以創(chuàng)建一個(gè)Handler,其實(shí)是可以的船响,但是誰(shuí)這么用啊- -

    new Thread() {
        Handler mHandler = null;
        @Override
        public void run() {
            //在這里獲取
            Looper.prepare();
            mHandler = new Handler();
            //在這里啟動(dòng)
            Looper.loop();
        }
    }.start();

多線程的創(chuàng)建

一般我們?cè)陂_(kāi)發(fā)過(guò)程中要開(kāi)啟一個(gè)線程都是直接

        new Thread() {
            @Override
            public void run() {
                doing.....
            }
        }.start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                doing.....
            }
        }).start();

注意看躬拢,一個(gè)傳遞了Runnable對(duì)象,另一個(gè)沒(méi)有,但是這兩個(gè)有什么不同见间,為什么要衍生出2個(gè)呢聊闯?
這里不去看源碼,簡(jiǎn)單敘述一下米诉,實(shí)際上Thread是Runnabled的一個(gè)包裝實(shí)現(xiàn)類馅袁,Runnable只有一個(gè)方法,就是run(),在這里以前也想過(guò)荒辕,為什么Runnable只有一個(gè)方法呢汗销,后來(lái)的某一次交談中也算是找到一個(gè)答案犹褒,可能是因?yàn)槎嗤卣梗赡躂AVA語(yǔ)言想拓展一些其他的東西弛针,以后就直接在Runnable再寫(xiě)了叠骑。不然我是沒(méi)有想到另一答案為什么都要傳遞一個(gè)Runnable,可能就像我們開(kāi)發(fā)中的baseActivity一樣吧


線程常用的操作方法

  • wait() 當(dāng)一個(gè)線程執(zhí)行到了wait() 就會(huì)進(jìn)去一個(gè)和對(duì)象有關(guān)的等待池中,同時(shí)失去了釋放當(dāng)前對(duì)象的機(jī)所削茁,使其他線程可以訪問(wèn)宙枷,也就是讓其他線程可以調(diào)用notify()喚醒
  • sleep() 調(diào)用得線程進(jìn)入睡眠狀態(tài),不能該改變對(duì)象的機(jī)鎖茧跋,其他線程不能訪問(wèn)
  • join() 就等自己完事
  • yidld 你急你先來(lái)

簡(jiǎn)單的白話敘述其實(shí)也就是這樣慰丛,希望能看看demo然后理解一下。


一些其他的方法瘾杭,Callable,Future,FutureTask

Runnable是線程管理的拓展接口诅病,不可以運(yùn)用于線程池,所以你總要有方法可以在線程池中管理啊所以Callable,Future,FutureTask就是可以在線程池中開(kāi)啟線程的接口。

Future定義了規(guī)范的接口粥烁,如get(),isDone(),isCancelled()...FutureTask是他的實(shí)現(xiàn)類這里簡(jiǎn)單說(shuō)一下他的用法

/**
 * ================================================
 * 作    者:夏沐堯  Github地址:https://github.com/XiaMuYaoDQX
 * 版    本:1.0
 * 創(chuàng)建日期: 2018/1/10
 * 描    述:
 * 修訂歷史:
 * ================================================
 */
class FutureDemo {
    //創(chuàng)建一個(gè)單例線程
    static ExecutorService mExecutor = Executors.newSingleThreadScheduledExecutor();

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ftureWithRunnable();
        ftureWithCallable();
        ftureTask();
    }

    /**
     * 沒(méi)有指定返回值贤笆,所以返回的是null,向線程池中提交的是Runnable
     *
     * @throws ExecutionException
     * @throws InterruptedException
     */
    private static void ftureWithRunnable() throws ExecutionException, InterruptedException {
        Future<?> result1 = mExecutor.submit(new Runnable() {
            @Override
            public void run() {
                fibc(20);
                System.out.println(Thread.currentThread().getName());
            }
        });
        System.out.println("Runnable" + result1.get());
    }

    /**
     * 提交了Callable,有返回值讨阻,可以獲取阻塞線程獲取到數(shù)值
     *
     * @throws ExecutionException
     * @throws InterruptedException
     */
    private static void ftureWithCallable() throws ExecutionException, InterruptedException {
        Future<Integer> result2 = mExecutor.submit(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                System.out.println(Thread.currentThread().getName());
                return fibc(20);
            }
        });
        System.out.println("Callable" + result2.get());
    }

    /**
     * 提交的futureTask對(duì)象
     * @throws ExecutionException
     * @throws InterruptedException
     */
    private static void ftureTask() throws ExecutionException, InterruptedException {
        FutureTask<Integer> futureTask = new FutureTask<Integer>(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                System.out.println(Thread.currentThread().getName());
                return fibc(20);
            }
        });
        mExecutor.submit(futureTask);
        System.out.println("futureTask" + futureTask.get());

    }

    private static int fibc(int num) {
        if (num == 0) {
            return 0;
        }
        if (num == 1) {
            return 1;
        }
        return fibc(num - 1) + fibc(num - 2);
    }
}

線程池

Java通過(guò)Executors提供線程池芥永,分別為:

  • newCachedThreadPool創(chuàng)建一個(gè)可緩存線程池,如果線程池長(zhǎng)度超過(guò)處理需要钝吮,可靈活回收空閑線程埋涧,若無(wú)可回收,則新建線程奇瘦。
  • newFixedThreadPool 創(chuàng)建一個(gè)定長(zhǎng)線程池飞袋,可控制線程最大并發(fā)數(shù),超出的線程會(huì)在隊(duì)列中等待链患。
  • newScheduledThreadPool 創(chuàng)建一個(gè)定長(zhǎng)線程池,支持定時(shí)及周期性任務(wù)執(zhí)行瓶您。
  • newSingleThreadExecutor 創(chuàng)建一個(gè)單線程化的線程池麻捻,它只會(huì)用唯一的工作線程來(lái)執(zhí)行任務(wù),保證所有任務(wù)按照指定順序(FIFO, LIFO, 優(yōu)先級(jí))執(zhí)行呀袱。

示例代碼

  • newCachedThreadPool
    創(chuàng)建一個(gè)可緩存線程池贸毕,如果線程池長(zhǎng)度超過(guò)處理需要,可靈活回收空閑線程夜赵,若無(wú)可回收明棍,則新建線程。示例代碼如下:
public class ThreadPoolExecutorTest {  
 public static void main(String[] args) {  
  ExecutorService cachedThreadPool = Executors.newCachedThreadPool();  
  for (int i = 0; i < 10; i++) {  
   final int index = i;  
   try {  
    Thread.sleep(index * 1000);  
   } catch (InterruptedException e) {  
    e.printStackTrace();  
   }  
   cachedThreadPool.execute(new Runnable() {  
    public void run() {  
     System.out.println(index);  
    }  
   });  
  }  
 }  
} 
線程池為無(wú)限大寇僧,當(dāng)執(zhí)行第二個(gè)任務(wù)時(shí)第一個(gè)任務(wù)已經(jīng)完成摊腋,會(huì)復(fù)用執(zhí)行第一個(gè)任務(wù)的線程沸版,而不用每次新建線程。
  • newFixedThreadPool
    創(chuàng)建一個(gè)定長(zhǎng)線程池兴蒸,可控制線程最大并發(fā)數(shù)视粮,超出的線程會(huì)在隊(duì)列中等待。示例代碼如下:
public class ThreadPoolExecutorTest {  
 public static void main(String[] args) {  
  ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);  
  for (int i = 0; i < 10; i++) {  
   final int index = i;  
   fixedThreadPool.execute(new Runnable() {  
    public void run() {  
     try {  
      System.out.println(index);  
      Thread.sleep(2000);  
     } catch (InterruptedException e) {  
      e.printStackTrace();  
     }  
    }  
   });  
  }  
 }  
}  
因?yàn)榫€程池大小為3橙凳,每個(gè)任務(wù)輸出index后sleep 2秒蕾殴,所以每?jī)擅氪蛴?個(gè)數(shù)字。
定長(zhǎng)線程池的大小最好根據(jù)系統(tǒng)資源進(jìn)行設(shè)置岛啸。如Runtime.getRuntime().availableProcessors()
  • newScheduledThreadPool
    創(chuàng)建一個(gè)定長(zhǎng)線程池钓觉,支持定時(shí)及周期性任務(wù)執(zhí)行。延遲執(zhí)行示例代碼如下:
public class ThreadPoolExecutorTest {  
 public static void main(String[] args) {  
  ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);  
  scheduledThreadPool.schedule(new Runnable() {  
   public void run() {  
    System.out.println("delay 3 seconds");  
   }  
  }, 3, TimeUnit.SECONDS);  
 }  
}  
表示延遲3秒執(zhí)行坚踩。

定期執(zhí)行示例代碼如下:

public class ThreadPoolExecutorTest {  
 public static void main(String[] args) {  
  ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);  
  scheduledThreadPool.scheduleAtFixedRate(new Runnable() {  
   public void run() {  
    System.out.println("delay 1 seconds, and excute every 3 seconds");  
   }  
  }, 1, 3, TimeUnit.SECONDS);  
 }  
}  
表示延遲1秒后每3秒執(zhí)行一次荡灾。
  • newSingleThreadExecutor
public class ThreadPoolExecutorTest {  
 public static void main(String[] args) {  
  ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();  
  for (int i = 0; i < 10; i++) {  
   final int index = i;  
   singleThreadExecutor.execute(new Runnable() {  
    public void run() {  
     try {  
      System.out.println(index);  
      Thread.sleep(2000);  
     } catch (InterruptedException e) {  
      e.printStackTrace();  
     }  
    }  
   });  
  }  
 }  
}  

這里只是簡(jiǎn)單敘述了一下線程的管理的各種方法,后續(xù)還會(huì)針對(duì)進(jìn)行講解
2018年1月17日下午8:19

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市堕虹,隨后出現(xiàn)的幾起案子卧晓,更是在濱河造成了極大的恐慌,老刑警劉巖赴捞,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件逼裆,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡赦政,警方通過(guò)查閱死者的電腦和手機(jī)胜宇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)恢着,“玉大人桐愉,你說(shuō)我怎么就攤上這事£桑” “怎么了从诲?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)靡羡。 經(jīng)常有香客問(wèn)我系洛,道長(zhǎng),這世上最難降的妖魔是什么略步? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任描扯,我火速辦了婚禮,結(jié)果婚禮上趟薄,老公的妹妹穿的比我還像新娘绽诚。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布恩够。 她就那樣靜靜地躺著卒落,像睡著了一般。 火紅的嫁衣襯著肌膚如雪玫鸟。 梳的紋絲不亂的頭發(fā)上导绷,一...
    開(kāi)封第一講書(shū)人閱讀 51,631評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音屎飘,去河邊找鬼妥曲。 笑死,一個(gè)胖子當(dāng)著我的面吹牛钦购,可吹牛的內(nèi)容都是我干的檐盟。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼押桃,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼葵萎!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起唱凯,我...
    開(kāi)封第一講書(shū)人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤羡忘,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后磕昼,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體卷雕,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年票从,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了漫雕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡峰鄙,死狀恐怖浸间,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情吟榴,我是刑警寧澤魁蒜,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站吩翻,受9級(jí)特大地震影響兜看,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜仿野,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望她君。 院中可真熱鬧脚作,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至亿扁,卻和暖如春捺典,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背从祝。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工襟己, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人牍陌。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓擎浴,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親毒涧。 傳聞我的和親對(duì)象是個(gè)殘疾皇子贮预,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355