轉:基礎學習總結----線程(一)http://www.cnblogs.com/xdp-gacl/p/3633936.htmljavahtml
1、線程的概念java
線程:線程是一個程序裏面不一樣的執行路徑多線程
進程:一個靜態的概念,機器上的一個.class文件,機器上的一個.exe文件,這個叫作一個進程。ide
程序的執行過程:學習
1.首先把程序的代碼放到內存的代碼區裏面,代碼放到代碼區後並無立刻開始執行,但這時候說明了一個進程準備開始,進程已經產生,但尚未開始執行,這就是進程。實際上是2.一進程的執行指的是進程裏面主線程(也就是main()方法)開始執行了。this
3.進程是一個靜態的概念,在咱們機器裏面實際上運行的都是線程。spa
4.實際上在一個時間點上,CPU只有一個線程在運行,由於CPU運行的速度很快,所以咱們看起來的感受就像是多線程同樣。線程
2、線程的建立和啓動3d
1.在JAVA裏面,JAVA的線程是經過java.lang.Thread類來實現的,每個Thread對象表明一個新的線程。code
2.你只要new一個Thread對象,一個新的線程也就出現了。
3.每一個線程都是經過某個特定的Thread對象所對應的方法run()來完成其操做的,方法run()稱爲線程體。
程序示例1:
public class TestThread1 { public static void main(String args[]) { //new一個線程類對象r1,r1要調用run()方法才能啓動 Runner1 r1 = new Runner1(); //要啓動一個新的線程t就必須new一個Thread對象出來 //這裏使用的是Thread(Runnable target)構造方法 Thread t = new Thread(r1); //啓動線程t,t線程執行的是run()方法,它與主線程r1會一塊兒並行執行 t.start(); for(int i = 0; i < 10; i++) { System.out.println("maintheod:" + i); } } } //定義一個類用來實現Runnable接口,實現Runnable接口就表示這個類是一個線程類 class Runner1 implements Runnable { public void run() { for(int i = 0; i <10; i++) { System.out.println("Runner1:" + i); } } }
程序精華解析:
程序運行結果:
不開闢新線程直接調用run方法
結果:
程序示例2:
繼承Thread類,並重寫它的run()方法建立和啓動新的線程
例子
public class TestThread2 { public static void main(String args[]) { Runner2 r2 = new Runner2(); r2.start(); for(int i = 0; i<=10; i++ ) { System.out.println("mainMethod:" + i); } } } //Runner2類從Thread類繼承 //經過實例化Runner2類的一個對象能夠開闢一個新的線程 //調用從Thread類繼承來的start()方法能夠啓動新開闢的線程 class Runner2 extends Thread { public void run() {//重寫run()方法的實現 for(int i=0;i<=10;i++) { System.out.println("Runner2:"+i); } } }
使用實現Runnable接口和繼承Thread類這兩種開闢新線程的方法的選擇應該優先選擇實現Runnable接口這種方式去開闢一個新的線程。由於接口的實現能夠實現多個,而類的繼承只能是單繼承。所以在開闢新線程時可以使用Runnable接口就儘可能不要使用從Thread類繼承的方式來開闢新的線程。
3、線程狀態轉換
import java.util.Date; public class sleep { public static void main(String args[]) { MyThread thread = new MyThread(); //調用start方法啓動新開闢的進程 thread.start(); try { MyThread.sleep(10000); //在哪一個線程裏面調用sleep()方法就讓哪一個線程睡眠,如今是主線程睡眠 System.out.println("主線程睡眠了10秒後再次啓動了"); }catch(InterruptedException e) { e.printStackTrace(); } //thread.interrupt();//使用interrupt()方法結束一個線程不是一個很好的作法 thread.flag = false;//改變循環條件,結束死循環 /** * 當發生InterruptedException時,直接把循環的條件設置爲false便可退出死循環, * 繼而結束掉子線程的執行,這是一種比較好的結束子線程的作法 */ /** * 調用interrupt()方法把正在運行的線程打斷 至關因而主線程一盆涼水潑上去把正在執行分線程打斷了 分線程被打斷以後就會拋InterruptedException異常,這樣就會執行return語句返回,結束掉線程的執行 因此這裏的分線程在執行完10秒鐘以後就結束掉了線程的執行 */ } } class MyThread extends Thread { //定義一個標誌用來控制循環的條件 boolean flag = true; public void run() { /* * 注意:這裏不能在run()方法的後面直接寫throw Exception來拋異常, * 由於如今是要重寫從Thread類繼承而來的run()方法,重寫方法不能拋出比被重寫的方法的不一樣的異常。 * 因此這裏只能寫try……catch()來捕獲異常 */ while(flag) { //toLocaleString返回一個表示該Date對象的"本地化"字符串, System.out.println("============" + new Date().toLocaleString()+ "========"); try { sleep(1000);//睡眠的時若是被打斷就會拋出InterruptedException異常 // 這裏是讓這個新開闢的線程每隔一秒睡眠一次,而後睡眠一秒鐘後再次啓動該線程 // 這裏在一個死循環裏面每隔一秒啓動一次線程,每一個一秒打印出當前的系統時間 }catch(InterruptedException e) { /* * 睡眠的時一盤冷水潑過來就有可能會打斷睡眠 * 所以讓正在運行線程被一些意外的緣由中斷的時候有可能會拋被打擾中斷(InterruptedException)的異常 */ return; // 線程被中斷後就返回,至關因而結束線程 } } } }
public class join { public static void main(String args[]) { //在建立一個新的線程對象的同時給這個線程對象命名爲mythread MyThread2 thread2 = new MyThread2("mythread"); //啓動線程 thread2.start(); try { //調用join()方法合併線程,將子程序mythread合併到主線程裏面 thread2.join(); //合併線程後,程序的執行的過程至關因而方法的調用的執行過程 }catch(InterruptedException e) { e.printStackTrace(); } for(int i = 0; i<= 5; i++) { System.out.println("I am main Thread"); } } } class MyThread2 extends Thread { MyThread2(String s) { super(s); /* * 使用super關鍵字調用父類的構造方法 * 父類Thread的其中一個構造方法:「public Thread(String name)」 * 經過這樣的構造方法能夠給新開闢的線程命名,便於管理線程 */ } public void run() { for(int i = 1;i<=5;i++) { System.out.println("I am a\t" + getName()); // 使用父類Thread裏面定義的 //public final String getName(),Returns this thread's name. try { //線程每執行一次就睡眠1秒鐘 sleep(1000); }catch(InterruptedException e) { return; } } } }