線程能夠驅動任務,所以你須要一種描述任務的方式,這能夠由Runnable接口來提供。要想定義任務,只需實現Runnable接口並編寫run方法,使得該任務能夠執行你的命令。java
public class LiftOff implements Runnable { protected int countDown = 10; private static int taskCount = 0; //id能夠用來區分任務的多個實例 private final int id = taskCount++; public LiftOff(){ System.out.println("調用了無參的構造函數"); } public LiftOff(int countDown){ this.countDown = countDown; System.out.println("調用了有參的構造函數\n"+ "參數內容爲:"+countDown); } public String status(){ return "#" + id + "(" + (countDown > 0 ? countDown : "Liftoff!") + "),"; } @Override public void run() { while(countDown-- > 0){ System.out.println(status()); //使當前線程從執行狀態(運行狀態)變爲可執行態(就緒狀態)。 //cpu會從衆多的可執行態裏選擇,也就是說, //當前也就是剛剛的那個線程仍是有可能會被再次執行到的, //並非說必定會執行其餘線程而該線程在下一次中不會執行到了。 Thread.yield(); } } public static void main(String[] args) { LiftOff test1 = new LiftOff(); test1.run(); System.out.println("\n"); LiftOff test2 = new LiftOff(5); test2.run(); } }
將Runnable對象轉變爲工做任務的傳統方式是把它提交給一個Thread構造器,
Thread構造器只須要一個Runnable對象。調用Thread對象的start()方法爲該線程執行必需的初始化操做,
而後調用Runnable的run()方法,以便在這個新線程中啓動該任務。由於main()方法和LiftOff.run()是由不一樣
的線程執行的,所以程序同時運行兩個方法。
編程
線程調度沒有順序的,由CPU決定。
併發
接下來經過java.util.concurrent包中的執行器(Executor)將爲你管理Thread對象,從而簡化了併發編程。ide
1:CachedThreadPool首先會按照須要建立足夠多的線程來執行任務(Task)。隨着程序執行的過程,有的線程執行完了任務,能夠被從新循環使用時,纔再也不建立新的線程來執行任務
對shutdown()方法的調用能夠防止新任務被提交給這個Executor,當前線程(即驅動main()的線程)將
繼續運行在shutdown()被調用以前提交的全部任務。這個程序將在Executor中的全部任務完成以後儘快退出。函數
2:FixedThreadPool模式會使用一個優先固定數目的線程來處理若干數目的任務。規定數目的線程處理全部任務,一旦有線程處理完了任務就會被用來處理新的任務(若是有的話)。
最好把3換成Runtime.getRuntime().availableProcessors(),這樣能更大程度利用你的電腦CPU處理。this
3:SingleThreadExecutor就像是線程數量爲1的FixedThreadPool。若是多個任務被提交給SingleThreadExecutor的話,那麼這些任務會被保存在一個隊列中,而且會按照任務提交的順序,一個先執行完成再執行另一個線程。SingleThreadExecutor模式能夠保證只有一個任務會被執行。這種特色能夠被用來處理共享資源的問題而不須要考慮同步的問題。
spa