Java基礎_17 | Java多線程程序設計(Java中兩種創建線程的方法、多線程之間的同步和互斥)

1. 多線程實現最核心的機制

一個程序在其執行過程中, 可以產生多個線程, 形成多條執行線索。,每條線程,有產生、存在和消亡的過程,並且獨立完成各自的功能,互不干擾。

多線程程序運行只佔用一個CPU,使用“時間片輪轉法”運行程序,如圖:

2. Java中的多線程實現

Java應用程序總是從主類的main()方法開始執行,如果main()方法中創建了其它線程,在主線程和其它線程之間輪流切換執行,保證每個線程都有機會使用CPU,直到程序中所有線程都結束, Java應用程序才結束。

在Java中,每個線程的狀態有以下四種:

線程狀態切換時調用的方法在圖中已標示出來,這些對線程進行操作的方法都在java.lang.Thread 類中,這個類是專門用來創建線程和對線程進行操作的類,還包括特殊的 run( )方法。

在Java中,創建線程有兩種方法:

  • 繼承Thread類
  • 實現Runnable接口

線程創建方法1—繼承Thread類

具體定義方法如下:

  • ① 定義類的時候繼承Thread類;
  • ② 重寫 Thread 類的 run() 方法;
  • ③ 準備在線程中完成的工作放在run() 方法實現;

定義之後創建對象,然後通過該對象調用start()方法即可啓動線程。

示例代碼如下:

import java.lang.Thread;

class MyThread extends Thread {
    String name;
    int count;
    MyThread(String name, int count){
        this.name = name;
        this.count = count;
    }

    public void run() {
        for(int i = 0; i < count;i++) {
            System.out.println(name + ":" + i);
        }
    }
}

public class ThreadTest {
    public static void main(String[] args) {
        //創建線程
        MyThread myThread1 = new MyThread("A",5);
        MyThread myThread2 = new MyThread("B",5);

        //啓動線程
        myThread1.run();
        myThread2.run();
    }
}

運行效果如下:

線程創建方法2—實現Runnable接口

具體定義方法如下:

  • ① 定義類的時候實現Runnable接口;
  • ② 重寫接口中的 run() 方法;
  • ③ 準備在線程中完成的工作放在run() 方法實現;

定義之後創建對象,然後通過該對象調用start()方法即可啓動線程。

示例代碼如下:

import java.lang.Thread;

class MyTestThread implements Runnable{
    String name;
    int count;
    MyTestThread(String name, int count){
        this.name = name;
        this.count = count;
    }

    public void run() {
        for(int i = 0; i < count;i++) {
            System.out.println(name + ":" + i);
        }
    }
}

public class ThreadTest2 {
    public static void main(String[] args) {
        //創建線程
        MyTestThread myThread1 = new MyTestThread("A",3);
        MyTestThread myThread2 = new MyTestThread("B",3);

        //啓動線程
        myThread1.run();
        myThread2.run();
    }
}

運行效果如下:

3. 多線程之間的同步和互斥

在多線程程序中,可能會有兩個甚至更多的線程試圖同時訪問一個有限的資源,在編寫程序時必須對這種潛在資源衝突進行預防。

爲了解決這種衝突,在線程使用一個資源時爲其加鎖即可,訪問資源的第一個線程爲其加上鎖以後,其他線程便不能再使用那個資源,除非被解鎖

加鎖的方法非常簡單,只需要對於訪問某個關鍵共享資源的所有方法,加上synchronized修飾符即可,比如:

synchronized void f();

加鎖之後,其它線程想使用這個方法時就必須等待,直到線程A 使用完該方法,除非線程A主動讓出CPU資源。

示例代碼如下:

import java.lang.Thread;

class MySyncThread implements Runnable{
    String name;
    int count;
    /* 所有該類對象共享資源 */
    private static int number = 100;

    MySyncThread(String name, int count){
        this.name = name;
        this.count = count;
    }

    public void run() {
        int temp;
        for(int i = 0; i < count;i++) {
            temp = sub();
            System.out.println(name + ":number = " + number);
            //主動掛起,讓出CPU
            try {
                Thread.sleep(2000);
            }
            catch (Exception e) {
                System.out.println("發生異常啦!");
            }
        }
    }

    /* 上鎖 */
    public  synchronized int sub() {
        number--;
        return number;
    }
}

public class ThreadTest3 {
    public static void main(String[] args) {
        //創建線程
        MySyncThread myThread1 = new MySyncThread("A",3);
        MySyncThread myThread2 = new MySyncThread("B",3);

        //啓動線程
        myThread1.run();
        myThread2.run();
    }
}

運行效果如下:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章