在 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
相关文章
如何在 Java 中延迟几秒钟的时间
发布时间:2023/12/17 浏览次数:217 分类:Java
-
本篇文章主要介绍如何在 Java 中制造程序延迟。本教程介绍了如何在 Java 中制造程序延时,并列举了一些示例代码来了解它。
如何在 Java 中把 Hashmap 转换为 JSON 对象
发布时间:2023/12/17 浏览次数:187 分类:Java
-
它描述了允许我们将哈希图转换为简单的 JSON 对象的方法。本文介绍了在 Java 中把 Hashmap 转换为 JSON 对象的方法。我们将看到关于创建一个 hashmap,然后将其转换为 JSON 对象的详细例子。
如何在 Java 中按值排序 Map
发布时间:2023/12/17 浏览次数:171 分类:Java
-
本文介绍了如何在 Java 中按值对 Map 进行排序。本教程介绍了如何在 Java 中按值对 Map
进行排序,并列出了一些示例代码来理解它。
如何在 Java 中打印 HashMap
发布时间:2023/12/17 浏览次数:192 分类:Java
-
本帖介绍了如何在 Java 中打印 HashMap。本教程介绍了如何在 Java 中打印 HashMap 元素,还列举了一些示例代码来理解这个主题。
在 Java 中更新 Hashmap 的值
发布时间:2023/12/17 浏览次数:146 分类:Java
-
本文介绍了如何在 Java 中更新 HashMap 中的一个值。本文介绍了如何在 Java 中使用 HashMap 类中包含的两个方法-put() 和 replace() 更新 HashMap 中的值。
Java 中的 hashmap 和 map 之间的区别
发布时间:2023/12/17 浏览次数:79 分类:Java
-
本文介绍了 Java 中的 hashmap 和 map 接口之间的区别。本教程介绍了 Java 中 Map 和 HashMap 之间的主要区别。在 Java 中,Map 是用于以键值对存储数据的接口,
在 Java 中获取用户主目录
发布时间:2023/12/17 浏览次数:218 分类:Java
-
这篇文章向你展示了如何在 Java 中获取用户主目录。本教程介绍了如何在 Java 中获取用户主目录,并列出了一些示例代码以指导你完成该主题。
Java 中 size 和 length 的区别
发布时间:2023/12/17 浏览次数:179 分类:Java
-
这篇文章教你如何知道 Java 中大小和长度之间的区别。本教程介绍了 Java 中大小和长度之间的区别。我们还列出了一些示例代码以帮助你理解该主题。
Java 中的互斥锁
发布时间:2023/12/17 浏览次数:111 分类:Java
-
了解有关 Java 中互斥锁的一切,在计算机科学领域,互斥或互斥被称为并发控制的属性。每台计算机都使用称为线程的最小程序指令序列。有一次,计算机在一个线程上工作。为了更好地理解,