線程的基本概念

    1、進程、線程和多線程的概念

進程是程序的一次動態執行過程,它經歷了從代碼加載、執行到執行完畢的一個完整過程,這個過程也是進程自己從產生、發展到最終消亡的過程。多進程操做系統能同時運行多個進程(程序),因爲 CPU 具有分時機制,因此每一個進程都能循環得到本身的 CPU 時間片。因爲 CPU 執行速度很是快,使得全部程序好象是在「同時」運行同樣。java

線程是比進程更小的執行單位,線程是進程內部單一的一個順序控制流。多線程

所謂線程是指一個進程在執行過程當中能夠產生多個線程,這些線程能夠同時存在、同時運行,造成多條執行線索。一個進程可能包含了多個同時執行的線程。併發

多線程是實現併發機制的一種有效手段。進程和線程同樣,都是實現併發的一個基本單位。線程和進程的主要差異體如今如下兩個方面:ide

( 1)、一樣做爲基本的執行單元,線程是劃分得比進程更小的執行單位。測試

( 2)、每一個進程都有一段專用的內存區域。與此相反,線程卻共享內存單元(包括代碼和數據),經過共享的內存單元來實現數據交換、實時通訊與必要的同步操做。spa

多線程和多進程的區別?操作系統

最本質的區別就是,每一個進程用於一整套的變量,而線程則是共享數據。並且,與進程相比較,線程更「輕量級」,建立、撤銷一個線程比啓動一個新進程的開銷要小不少。
命令行


 2、線程的基本實例       

未使用多線程線程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Test {
     public static void main(String[] args) {
         new TestThraed().run();
         for ( int i = 0 ; i < 10 ; i++) {
             System.out.println( "main方法在運行" +i);
         }
     }
}
class TestThraed {
     public void run() {
         for ( int i = 0 ; i < 10 ; i++) {
             System.out.println( "TestThread在運行" +i);
         }
     }
}

上面這段代碼是沒有使用多線程的狀況,程序輸出結果是按順序執行的,也就是先調用TestThread中的run方法,而後再執行main中的for循環代理

TestThread在運行0

........省略部分..........

TestThread在運行9

main方法在運行0

........省略部分..........

main方法在運行9

當使用多線程的時候

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Test {
     public static void main(String[] args) {
         /**
          * 開啓一個新線程並啓動它【不要直接調用run方法】
          * 若是直接調用Thread.run()方法,只會執行同一線程【main線程】的任務,而不會啓動新線程。
          */
         new TestThraed().start();
         for ( int i = 0 ; i < 10 ; i++) {
             System.out.println( "main方法在運行" +i);
         }
     }
}
class TestThraed extends Thread{
     @Override
     public void run() {
         for ( int i = 0 ; i < 10 ; i++) {
             System.out.println( "TestThread在運行" +i);
         }
     }
}

使用了多線程後,程序的結果是交叉執行的。也就是在main線程中開闢了一個新的線程。因爲main自己也佔用一條線程,實際上在命令行中運行 java 命令時,就啓動了一個 JVM 的進程,默認狀況下此進程會產生兩個線程:一個是 main()方法線程,另一個就是垃圾回收( GC)線程因此這裏是兩條線程main線程和new TestThread().start()線程。兩個線程同時交替運行着。

結果以下:

main方法在運行0

TestThread在運行0

main方法在運行1

TestThread在運行1

........省略部分..........

main方法在運行8

main方法在運行9

TestThread在運行8

TestThread在運行9


 3、建立線程的兩種方式      

要想使某個程序是多線程運行的,能夠將其變爲多線程的程序。多線程程序的run方法中才是該多線程須要執行分解任務的邏輯。任意一個類都是能夠變成多線程程序的。

建立線程的方式有以下兩種:

1.實現Runnable接口,該接口中只有一個抽象的run方法 public abstract void run();

2.繼承Thread類,其實Thread類內部也是實現了Runnable接口。只不過內部封裝了對線程的一些經常使用操做。

3.1 實現Runnable接口的方式建立線程:實現Runnable接口,重寫run方法      

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//實現Runnable接口的方式來建立線程
public class Programmer implements Runnable{
     @Override
     public void run() {
         for ( int i = 0 ; i < 100 ; i++) {
             System.out.println( "第" +i+ "次" );
         }
     }
}
//測試多線程
public class TestProgrammer {
     public static void main(String[] args) {
         //1.建立真實角色
         Programmer pro = new Programmer();
         //2.建立代理角色+真實角色的引用
         Thread proxy = new Thread(pro);
         //3.調用start方法,啓動線程
         proxy.start();
         for ( int i = 0 ; i < 100 ; i++) {
             System.out.println( "QQ" );
         }
     }
}

3.2 繼承Thread類方式來建立線程:繼承Thread類,重寫run方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//繼承Thread類的方式來建立線程
public class Rabbit extends Thread {
     @Override
     public void run() {
         for ( int i = 0 ; i < 10 ; i++) {
             System.out.println( "兔子跑了" +i+ "步" );
         }
     }
       
}
//測試多線程
public class TestThread {
     public static void main(String[] args) {
         Rabbit rabbit = new Rabbit();
         rabbit.start(); //不要調用run方法
     }
}

警告:啓動線程時,不要直接調用Thread或者Runnable接口的run方法,直接調用run方法只會執行同一個線程中的任務。而不會啓動新線程。

應該調用Thread.start()方法。這個方法將建立一個執行run方法的新線程。


 4、總結       

一、線程和進程的區別?

進程是一個程序的動態執行過程,它會在CPU給分配的一塊內存中執行一段程序【一我的在一個房間裏執行一個程序】

線程只是比進程更小的執行單位,它是進程內部單一的一個順序控制流。

多線程則是把一個任務進行分解,一個程序在內存執行的時候產生多個線程,多線程共享某塊數據。讓多個線程來執行該一個程序【多我的在一個房間執行一個程序】

一個進程中可能包括多個線程,一個線程只能屬於一個進程。

二、線程的建立方式?

繼承Thread類或者實現Runnable接口

三、繼承Thread類仍是實現Runnable接口?

推薦實現Runnable接口,避免單繼承問題

四、線程的啓動?

啓動一個線程須要調用start()方法,不要直接調用run方法。run方法只會執行同一個線程中的任務而不會去開啓新線程。start方法是建立一個執行run方法的新線程。





相關文章
相關標籤/搜索