在 Java 中创建并发列表

Rashmi Patidar 2023年1月30日 2021年10月2日
  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 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