Java 多線程

2021-02-24 14:51 更新

Java線程教程 - Java多線程


以下代碼顯示了如何在程序中運行多線程。

public class Main {
  public static void main(String[] args) {
    // Create two Thread objects
    Thread t1 = new Thread(Main::print);
    Thread t2 = new Thread(Main::print);

    // Start both threads
    t1.start();
    t2.start();
  }

  public static void print() {
    for (int i = 1; i <= 500; i++) {
      System.out.println(i);
    }
  }
}

上面的代碼生成以下結果。

線程同步

Java編程語言內置了兩種線程同步:

  • 互斥同步
  • 條件同步

在互斥同步中,在一個時間點只允許一個線程訪問代碼段。

條件同步通過條件變量和三個操作來實現(xiàn):等待,信號和廣播。


同步關鍵字

synchronized關鍵字用于聲明需要同步的關鍵部分。

有兩種方法可以使用synchronized關鍵字:

  • 將方法聲明為關鍵部分
  • 將語句塊聲明為關鍵段

我們可以通過在方法的返回類型之前使用關鍵字synchronized來聲明一個方法作為臨界段。

public class Main {
  public synchronized void someMethod_1() {
    // Method code goes here
  }

  public static synchronized void someMethod_2() {
    // Method code goes here
  }
}

我們可以聲明一個實例方法和一個靜態(tài)方法同步。構造函數(shù)不能聲明為同步。

以下代碼說明了使用關鍵字synchronized:

public class Main {
  public synchronized void someMethod_1() {
    // only one thread can execute here at a time
  }

  public void someMethod_11() {
    synchronized (this) {
      // only one thread can execute here at a time
    }
  }

  public void someMethod_12() {
    // multiple threads can execute here at a time
    synchronized (this) {
      // only one thread can execute here at a time
    }
    // multiple threads can execute here at a time
  }

  public static synchronized void someMethod_2() {
    // only one thread can execute here at a time
  }

  public static void someMethod_21() {
    synchronized (Main.class) {
      // only one thread can execute here at a time
    }
  }

  public static void someMethod_22() {
    // multiple threads can execute here at a time
    synchronized (Main.class) {
      // only one thread can execute here at a time
    }
    // multiple threads can execute here at a time
  }
}

wait()方法

對wait()方法的調用必須放在synchronized方法或同步塊中。

對于當前線程已經(jīng)獲取監(jiān)視器的對象,必須調用wait()方法。

notify()方法

沒有辦法喚醒等待集中的特定線程。

例子

public class Main {
  private static int myValue = 1;

  public static void main(String[] args) {
    Thread t = new Thread(() -> {
      while (true) {
        updateBalance();
      }
    });
    t.start();
    t = new Thread(() -> {
      while (true) {
        monitorBalance();
      }
    });
    t.start();
  }

  public static synchronized void updateBalance() {
    System.out.println("start:" + myValue);
    myValue = myValue + 1;
    myValue = myValue - 1;
    System.out.println("end:" + myValue);
  }

  public static synchronized void monitorBalance() {
    int b = myValue;
    if (b != 1) {
      System.out.println("Balance  changed: " + b);
      System.exit(1); 
    }
  }
}

上面的代碼生成以下結果。

例2

以下代碼顯示了上述代碼的非同步版本。

public class Main {
  private static int myValue = 1;

  public static void main(String[] args) {
    Thread t = new Thread(() -> {
      while (true) {
        updateBalance();
      }
    });
    t.start();
    t = new Thread(() -> {
      while (true) {
        monitorBalance();
      }
    });
    t.start();
  }

  public static  void updateBalance() {
    System.out.println("start:" + myValue);
    myValue = myValue + 1;
    myValue = myValue - 1;
    System.out.println("end:" + myValue);
  }

  public static synchronized void monitorBalance() {
    int b = myValue;
    if (b != 1) {
      System.out.println("Balance  changed: " + b);
      System.exit(1); 
    }
  }
}

上面的代碼生成以下結果。

以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號