1. 程式人生 > >java多線程_01_線程的基本概念

java多線程_01_線程的基本概念

bool 我們 優先 try 立即執行 合並 abcde rup unix

線程:一個程序裏邊不同的執行路徑

技術分享

例子程序:這個例子程序是一條執行路徑。這個程序只有一個分支,就是main方法,叫主線程

public static void main(String[] args) {
        m1();
    }
    public static void m1(){
        m2();
        m3();
    }
    public static void m2(){}
    public static void m3(){}

程序執行示意圖:

技術分享

進程:進程是一個靜態的概念,機器上的一個class文件,一個exe文件。

程序的執行過程,要把程序的代碼放到內存裏,放到代碼區裏,一個進程準備開始,進程已經產生了,但還沒有開始執行,這叫進程。是一個靜態的概念。平時說的進程的執行說的是進程裏面主線程開始執行了。在機器裏面運行的實際上都是線程。 

我們的windows同時運行著好多個線程,所以說機器是支持多線程的。當然也支持多進程。windows、linux、unix都是多進程、多線程的,dos是只支持單進程的,同一個時間點只能執行一個進程執行。

CPU計算速度快,把自己的時間分成一個個時間片,這個時間片執行你一會,下一個時間片執行它一會,輪著來。雖然有幾十個線程,輪著執行由於速度很快,在我們看來就像是多個線程同時執行的。但實際上,一個時間點上,CUP只有一個線程在運行。(如果機器是多核,有多個CPU,才是真正意義上的多線程)

技術分享

實現Runnable接口:

package thread;

public class TestThread01 {
    public static void main(String[] args) {
        Runner1 r = new Runner1();
        Thread t = new Thread(r);
        t.start();//啟動線程,通知CPU線程已經準備好了,有空了來執行我一會
        
        for (int i = 0; i < 100; i++) {
            System.out.println(
"------Main Thread: "+i); } } } class Runner1 implements Runnable{ @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println("Runner1 : "+i); } } }

執行結果:輪著執行

技術分享

繼承Thread類:

package thread;

public class TestThread01 {
    public static void main(String[] args) {
        
        Runner1 r = new Runner1();
        r.start();//本身就是Thread,直接調用start
//        Thread t = new Thread(r);
//        t.start();//啟動線程,通知CPU線程已經準備好了,有空了來執行我一會
        
        for (int i = 0; i < 100; i++) {
            System.out.println("------Main Thread: "+i);
        }
    }
}
//class Runner1 implements Runnable{
class Runner1 extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("Runner1 : "+i);
        }
    }
}

能實現接口就不繼承Thread類。

線程的狀態轉換:

技術分享

一個線程類,new出來只是內存裏的一個對象。調用start方法,不是立即執行,而是就緒狀態,排隊等候,因為CPU可能正在執行其他的線程。CPU高興了,把對象調到CPU裏才得以執行。執行的過程中,可能你的時間片到頭了,還回到就緒狀態去排隊去,等候下次輪到你,一直到執行完了,就終止了。

運行過程中,可能有情況發生了,你必須要等到情況解決了才能繼續運行,這叫阻塞狀態。

技術分享

優先級越高的線程,獲得的CPU執行的時間越多。

技術分享

Sleep:

package thread;

import java.util.*;

public class TestInterrupt {
    public static void main(String[] args) {
        MyThread thread = new MyThread();
        thread.start();//啟動線程
        try {
            //主線程睡10秒,執行MyThread,打印10個時間
            Thread.sleep(10000);
        } catch (InterruptedException e) {
        }
        //打印10個時間後執行到此,調用interrupt方法中斷線程。
        thread.interrupt();
    }
}

class MyThread extends Thread {
    boolean flag = true;
    public void run() {
        while (flag) {
            System.out.println("===" + new Date() + "===");
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                return;
            }
        }
    }
}

結果:打印10個時間後,線程結束 。 Run方法一結束,線程就結束了

===Mon Jun 26 22:19:40 CST 2017===
===Mon Jun 26 22:19:41 CST 2017===
===Mon Jun 26 22:19:42 CST 2017===
===Mon Jun 26 22:19:43 CST 2017===
===Mon Jun 26 22:19:44 CST 2017===
===Mon Jun 26 22:19:45 CST 2017===
===Mon Jun 26 22:19:46 CST 2017===
===Mon Jun 26 22:19:47 CST 2017===
===Mon Jun 26 22:19:48 CST 2017===
===Mon Jun 26 22:19:49 CST 2017===

Join:合並某個線程,(等待該線程終止)

代碼:

package thread;

public class TestJoin {
  public static void main(String[] args) {
    MyThread2 t1 = new MyThread2("abcde");
    t1.start();
    try {
        /**
         * 把t1線程合並到主線程,即等待t1線程執行完,再執行主線程
         * 相當於方法調用
         */
        t1.join();
    } catch (InterruptedException e) {}
    //等t1執行完了,才有機會執行這
    for(int i=1;i<=10;i++){
      System.out.println("i am main thread");
    }
  }
}
class MyThread2 extends Thread {
  MyThread2(String s){//給線程起名字
      super(s);
  }
  
  public void run(){
    for(int i =1;i<=10;i++){
      System.out.println("i am "+getName());
      try {
          sleep(1000);
      } catch (InterruptedException e) {
          return;
      }
    }
  }
}

join把t1合並到主線程,main會等待著t1執行完,再執行自己。

技術分享

結果:

i am abcde
i am abcde
i am abcde
i am abcde
i am abcde
i am abcde
i am abcde
i am abcde
i am abcde
i am abcde
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread

Yield:

package thread;

public class TestYield {
  public static void main(String[] args) {
    MyThread3 t1 = new MyThread3("------t1");
    MyThread3 t2 = new MyThread3("t2");
    t1.start();
    t2.start();
  }
}
class MyThread3 extends Thread {
  MyThread3(String s){super(s);}
  public void run(){
    for(int i =1;i<=100;i++){
      System.out.println(getName()+": "+i);
      if(i%10==0){//能被10整除,讓出時間片,不明顯
        yield();
      }
    }
  }
}

結果:應該每到整除10,就讓給其他線程,但是不明顯。

------t1: 1
------t1: 2
------t1: 3
------t1: 4
------t1: 5
------t1: 6
------t1: 7
------t1: 8
------t1: 9
------t1: 10
t2: 1
t2: 2
t2: 3
t2: 4
t2: 5
t2: 6
------t1: 11

。。。。。

線程的優先級:

package thread;

public class TestPriority {
    public static void main(String[] args) {
        Thread t1 = new Thread(new T1());
        Thread t2 = new Thread(new T2());
        t1.setPriority(Thread.NORM_PRIORITY + 3);
        t1.start();
        t2.start();
    }
}

class T1 implements Runnable {
    public void run() {
        for(int i=0; i<1000; i++) {
            System.out.println("T1: " + i);
        }
    }
}

class T2 implements Runnable {
    public void run() {
        for(int i=0; i<1000; i++) {
            System.out.println("------T2: " + i);
        }
    }
}

結果:不明顯

T1: 0
T1: 1
T1: 2
T1: 3
T1: 4
T1: 5
T1: 6
T1: 7
T1: 8
T1: 9
T1: 10
T1: 11
T1: 12
T1: 13
T1: 14
T1: 15
T1: 16
T1: 17
T1: 18
T1: 19
T1: 20
T1: 21
T1: 22
T1: 23
T1: 24
T1: 25
T1: 26
T1: 27
T1: 28
T1: 29
T1: 30
T1: 31
T1: 32
T1: 33
T1: 34
T1: 35
T1: 36
T1: 37
T1: 38
T1: 39
T1: 40
T1: 41
T1: 42
T1: 43
T1: 44
T1: 45
T1: 46
T1: 47
T1: 48
T1: 49
T1: 50
T1: 51
T1: 52
T1: 53
T1: 54
T1: 55
T1: 56
T1: 57
T1: 58
T1: 59
T1: 60
T1: 61
T1: 62
T1: 63
T1: 64
T1: 65
T1: 66
T1: 67
T1: 68
T1: 69
T1: 70
T1: 71
T1: 72
T1: 73
T1: 74
T1: 75
T1: 76
T1: 77
T1: 78
T1: 79
T1: 80
T1: 81
T1: 82
T1: 83
T1: 84
T1: 85
T1: 86
T1: 87
T1: 88
T1: 89
T1: 90
T1: 91
T1: 92
T1: 93
T1: 94
T1: 95
T1: 96
T1: 97
T1: 98
T1: 99
T1: 100
T1: 101
T1: 102
T1: 103
T1: 104
T1: 105
T1: 106
T1: 107
T1: 108
T1: 109
T1: 110
------T2: 0
T1: 111
------T2: 1
T1: 112
------T2: 2
T1: 113
------T2: 3
T1: 114

java多線程_01_線程的基本概念