在 Java 中建立併發列表

Rashmi Patidar 2023年10月12日
  1. Java 中的驅動類
  2. Java 中的執行緒類
  3. 在 Java 中使用 run 方法
在 Java 中建立併發列表

併發是在並行執行中執行程式或函式的過程。當多個執行緒在同一個方法上工作時,它可以減少時間並增加吞吐量。

Java 提供了 CopyOnWriteArrayList 類,它允許一種有效的 List 操作方式,並且這些函式以執行緒安全的方式工作。這意味著當兩個或多個執行緒嘗試操作列表時,給定的類允許以執行緒安全的方式進行讀寫操作。在內部,當修改列表介面的方法(例如 addremove 函式)時,CopyOnWriteArrayList 的內容會被複制到新的內部副本中。此功能使其成為執行緒安全的並允許並行處理。

CopyOnWriteArrayList 類存在於 java.util.concurrent 包中。下面是一個程式碼塊示例,演示了對給定類的操作。

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class ConcurrentListOperations {
  public static void main(String[] args) {
    List<Integer> temp_list = Arrays.asList(1, 2, 3);
    List<Integer> list = new CopyOnWriteArrayList<>(temp_list);
    new WriteThread("Writer", list).start();
    new ReadThread("Reader", list).start();
  }
}

class WriteThread extends Thread {
  private final List<Integer> list;
  public WriteThread(String name, List<Integer> list) {
    this.list = list;
    super.setName(name);
  }

  public void run() {
    int count = 4;
    int counter = 0;
    do {
      try {
        Thread.sleep(5000);
      } catch (InterruptedException ex) {
        ex.printStackTrace();
      }
      list.add(count++);
      System.out.println(super.getName() + " done");
      counter++;
    } while (counter != 5);
  }
}

class ReadThread extends Thread {
  private final List<Integer> list;
  public ReadThread(String name, List<Integer> list) {
    this.list = list;
    super.setName(name);
  }

  public void run() {
    while (true) {
      StringBuilder output = new StringBuilder("\n" + super.getName() + ":");
      for (Integer nextVal : list) {
        output.append(" ").append(nextVal);
      }
      System.out.println(output);
    }
  }
}

Java 中的驅動類

在上面的程式中,定義了三個類。帶有 main 方法的第一個是驅動類,其他的用於執行。在 ConcurrentListOperations 類中,臨時列表最初使用三個整數進行初始化。形成的 temp_list 被傳遞到 CopyOnWriteArrayList 建構函式,這是另一種型別的 ArrayList 類。

該類使用上面定義的值初始化陣列。現在,copyOnWriteArrayList 的例項被傳遞給之前建立的執行緒類。這個類只會使列表執行緒安全;因此,允許對列表例項進行並行操作。

Java 中的執行緒類

兩個執行緒類是 ReadThreadWriteThread。該類的實際工作是同時讀寫同一個列表。WriteThread 類擴充套件了 Thread 類,這是宣告執行緒的一種方式。它有一個公共建構函式,用於將接收到的列表例項分配給區域性變數並初始化執行緒名稱。

執行緒的實際業務邏輯存在於它們的 run 方法中。要啟動一個執行緒,在新建立的執行緒類例項上呼叫 start 方法。

在 Java 中使用 run 方法

WriteThread 類的 run 方法中,在迴圈條件中初始化一個計數器以跟蹤 run 方法中 write 類的迭代。do-while 迴圈用於跟蹤迭代執行的次數。

在條件塊中,呼叫 Thread 類的 sleep 方法使執行緒在定義的時間內休眠。該函式使並行執行執行緒休眠一定的毫秒數。如果傳遞的毫秒數為負,則丟擲 IllegalArgumentException,如果任何執行緒被中斷,則丟擲 InterruptedException

add 方法用於通過併發執行緒在列表中新增元素。如果列表例項不允許該操作,它會丟擲 UnsupportedOperationException。另一方面,如果指定元素的類與列表的型別不同,它會丟擲 ClassCastException。如果指定值為 null,則丟擲 NullPointerException,如果此元素的某些屬性阻止新增元素,則丟擲 IllegalArgumentException

同樣,在 ReadThread 類的 run 方法中,定義了一個建構函式;它初始化名稱和列表。run 方法具有實際的 read 邏輯。StringBuilder 類用於在輸出中進行操作。append 方法將在寫入執行緒類中找到的輸出與現有的輸出相附加。

因此,readwrite 操作同時發生並以上述格式列印在控制檯中。寫入執行緒休眠大約 5000 毫秒,與讀取執行緒相比,寫入器輸出顯示的次數更少。... 表示執行緒無休止地執行並列印相同的輸出,因為沒有進行 write 操作。一旦寫入過程成功,讀取執行緒現在會列印新新增的值。

輸出:

Reader: 1 2 3 
..
Writer done
Reader: 1 2 3 4
...
Writer done
Reader: 1 2 3 4 5
作者: Rashmi Patidar
Rashmi Patidar avatar Rashmi Patidar avatar

Rashmi is a professional Software Developer with hands on over varied tech stack. She has been working on Java, Springboot, Microservices, Typescript, MySQL, Graphql and more. She loves to spread knowledge via her writings. She is keen taking up new things and adopt in her career.

LinkedIn

相關文章 - Java List