在 Java 中建立併發列表
併發是在並行執行中執行程式或函式的過程。當多個執行緒在同一個方法上工作時,它可以減少時間並增加吞吐量。
Java 提供了 CopyOnWriteArrayList
類,它允許一種有效的 List
操作方式,並且這些函式以執行緒安全的方式工作。這意味著當兩個或多個執行緒嘗試操作列表時,給定的類允許以執行緒安全的方式進行讀寫
操作。在內部,當修改列表介面的方法(例如 add
或 remove
函式)時,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 中的執行緒類
兩個執行緒類是 ReadThread
和 WriteThread
。該類的實際工作是同時讀寫同一個列表。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
方法將在寫入執行緒類中找到的輸出與現有的輸出相附加。
因此,read
和 write
操作同時發生並以上述格式列印在控制檯中。寫入執行緒休眠大約 5000 毫秒,與讀取
執行緒相比,寫入器輸出顯示的次數更少。...
表示執行緒無休止地執行並列印相同的輸出,因為沒有進行 write
操作。一旦寫入
過程成功,讀取
執行緒現在會列印新新增的值。
輸出:
Reader: 1 2 3
..
Writer done
Reader: 1 2 3 4
...
Writer done
Reader: 1 2 3 4 5
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