1. 程式人生 > 實用技巧 >Java多執行緒總結

Java多執行緒總結

Java多執行緒

在Java的JDK開發包中,已經自帶了對多執行緒技術的支援,可以很方便地進行多執行緒程式設計。實現多執行緒程式設計的方式有兩種,一種是繼承 Thread 類,另一種是實現 Runnable 介面。使用繼承 Thread 類建立執行緒,最大的侷限就是不能多繼承,所以為了支援多繼承,完全可以實現 Runnable 介面的方式。

繼承 Thread 類

// 繼承  Thread類 重寫 run()方法
public class ThreadDemo1 extends Thread {

    @Override
    public void run() {
        
for (int i = 0; i < 20; i++) { System.out.println(Thread.currentThread().getName() + " ---> " + i); } } public static void main(String[] args) { ThreadDemo1 t1 = new ThreadDemo1(); // 通過 start()開啟一個執行緒 t1.start(); for (int i = 0; i < 20; i++) { System.out.println(Thread.currentThread().getName()
+ " ---> " + i); } } }

2.實現 Runnable 介面

// 通過實現 Runnable介面,實現 run()方法
public class ThreadDemo2 implements Runnable {

    @Override
    public void run() {

        for (int i = 0; i < 20; i++) {
            System.out.println(Thread.currentThread().getName() + "   ---> " + i);
        }
    }

    
public static void main(String[] args) { ThreadDemo2 td2 = new ThreadDemo2(); // 通過 Thread類的構造器,傳入 Runnale型別的物件 Thread t1 = new Thread(td2); // 呼叫 Thread的 start()開啟執行緒 t1.start(); for (int i = 0; i < 20; i++) { System.out.println(Thread.currentThread().getName() + " ---> " + i); } } }

Thread.java 類中的start()方法通知“執行緒規劃器”此執行緒已經準備就緒,等待呼叫執行緒物件的run()方法。這個過程其實就是讓系統安排一個時間來呼叫 Thread 中的 run() 方法,也就是使執行緒得到執行,多執行緒是非同步的,執行緒在程式碼中啟動的順序不是執行緒被呼叫的順序。

當時使用多個執行緒操作同一個變數時,就會產生 執行緒安全問題。

為解決這樣的資料錯誤問題。需要使用 synchronized 關鍵字

synchronized() {將要被同步的程式碼寫在打括號中} 為同步程式碼塊

while (true) {
    // 同步程式碼塊
    synchronized (this) {
        // 喚醒所有正在等待的執行緒
        //  notifyAll();
        if (ticket > 0) {

            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println(Thread.currentThread().getName() + " ---> " + ticket + " 號票 已賣出 ,還剩餘 " + --ticket + " 票");
            try {
                // 當前執行緒等待
                //  wait();
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            // 跳出迴圈
            break;
        }
    }

synchronized 可以修飾程式碼塊,也可以修飾在方法上,public 後面

@Override
public synchronized void run() {
    while (true) {
        // 對要同步的 程式碼塊 加鎖
        //            synchronized (this) {
        // 喚醒一個執行緒
        notify();
        if (num <= 100) {
            try {
                // 執行緒睡眠 10毫秒
                Thread.sleep(30);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "  -->  " + num);
            num++;
            try {
                // 當前執行緒列印完以後等待,等待被下一個執行緒喚醒
                wait();
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            break;
            //                }
        }
    }
}

多執行緒是非同步的,執行緒在程式碼中啟動的順序不是執行緒被呼叫的順序。

對於如何設定將執行緒同步執行。即一個一個的按照順序執行?

需要使用Object的APi中的一些方法。

  • wait():等待,如果執行緒執行了wait方法,那麼該執行緒會進入等待的狀態,等待狀態下的執行緒必須要被其他執行緒呼叫notify()方法才能喚醒。

  • notify():喚醒,喚醒執行緒池等待執行緒其中的一個。

  • notifyAll():喚醒執行緒池所有等待執行緒。

注意!

wait與notify方法要注意的事項:

  1. wait方法與notify方法是屬於Object物件的。

  1. wait方法與notify方法必須要在同步程式碼塊或者是同步函式中才能使用。

  1. wait方法與notify方法必須要由所物件呼叫。



多執行緒方法API

1、currentThread()方法

currentThread()方法可返回程式碼段正在被哪個執行緒呼叫的資訊。

Thread.currentThread().getName()

2、isAlive()方法

方法isAlive()的功能是判斷當前的執行緒是否處於活動狀態。

thread.isAlive();

3、sleep()方法

方法sleep()的作用是在指定的毫秒數內讓當前"正在執行的執行緒"休眠(暫停執行)。這個"正在執行的執行緒"是指this.currentThread()返回的執行緒。

Thread.sleep()

4、getId()方法

getId()方法的作用是取得執行緒的唯一標識。

thread.getId()