gpt4 book ai didi

Java:测试服务的并发性

转载 作者:太空宇宙 更新时间:2023-11-04 09:39:39 25 4
gpt4 key购买 nike

我有一个服务类,其中包含添加 Student 的方法。到 Section 。现在每个Section有一个setStudents与之相关。

此外,还有一个Map<Section, Set<Student>>定义两者之间的关系。

service看起来像这样 addStudent方法:

public class MembershipService {

private final Map<Section, Set<Student>> studentsBySection = new HashMap<>();


public void addStudentToSection(Student student, Section sec) {

Set<Student> students = studentsBySection.get(sec);
if (students == null) {
students = new HashSet<>();
studentsBySection.put(sec, students);
}
students.add(student);

}
// ..... also containing helper method : getStudents(Section s)

我需要测试多线程场景中的功能,在该场景中,我需要展示如果两个或多个线程尝试从公共(public) map 添加或读取学生,将会发生什么情况。 .

我清楚地知道替换 HashmapConcurrentHashMap将解决我的目的,但无法展示确切的行为。

我的解决方案

我创建了两个线程:Student1Student2并尝试传递相同的 Service两者的实例并执行添加。 hashmap 的预期行为应该是ConcurrentModificationException并与 ConcurrentHashMap它不应该抛出。但它没有显示预期的行为,并且即使使用 HashMap 也能正常工作。 。请指导。

这是代码:

学生1

public class Student1 implements Runnable{

Services services;

public Student1(Services ser) {
this.services = ser;
new Thread(this, "Student 1").start();
}



@Override
public void run() {
final Student ALEX = new Student("alex");


services.getMembershipService().addStudentToSection(ALEX,services.getSection());;

try {
System.out.println("Student 1 sleeping");
Thread.sleep(100);
} catch (Exception e) {
System.out.println(e);
}

}

}

学生2

  public class Student2 implements Runnable{

Services services;

public Student2(Services ser) {
this.services = ser;
new Thread(this, "Student 2").start();
}



@Override
public void run() {
final Student JOHN = new Student("john");


services.getMembershipService().addStudentToSection(JOHN,services.getSection());;

try {
System.out.println("Student 2 sleeping");
Thread.sleep(100);
} catch (Exception e) {
System.out.println(e);
}

}

}

Tester.java

public static void main(String[] args) {
final Services services = ServiceFactory.createServices();
final Section A = new Section("A");
services.createSection(A);

Student1 one = new Student1(services);
Student2 two = new Student2(services);

}

我如何证明我的情况?

注意:这不是关于 How ConcurrentHashMap works in java或多线程。我知道这一点。我只是无法使其符合我的要求。

最佳答案

首先,ConcurrentModificationException 仅由迭代器抛出,而不是 put()/get()

The iterators returned by all of this class's "collection view methods" * are fail-fast: if the map is structurally modified at any time after * the iterator is created, in any way except through the iterator's own * remove method, the iterator will throw a * {@link ConcurrentModificationException}. Thus, in the face of concurrent * modification, the iterator fails quickly and cleanly, rather than risking * arbitrary, non-deterministic behavior at an undetermined time in the * future.

证明 Hashmap 在这种情况下不是线程安全的好方法是更改​​ Section 类以从 hashCode() 方法返回常量(以使失败更快)。

然后,您只需创建 1000 个不同的 Section 对象,并尝试调用您的服务以将学生映射到多个线程中的部分。基本上,当您完成将学生映射到部分时, map 上的大小将与部分的数量不匹配,它将小于不同部分的数量。

关于Java:测试服务的并发性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56118386/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com