RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1502619
Accepted
stepanevgen2013
stepanevgen2013
Asked:2023-03-06 21:12:48 +0000 UTC2023-03-06 21:12:48 +0000 UTC 2023-03-06 21:12:48 +0000 UTC

线程缓存和 RAM

  • 772

有如下代码,stream只是简单的将数字按升序添加到列表中:

 List<Integer> integers = new ArrayList<>();

    ListThread listThread1 = new ListThread(integers);
    ListThread listThread2 = new ListThread(integers);
    ListThread listThread3 = new ListThread(integers);
    ListThread listThread4 = new ListThread(integers);
    ListThread listThread5 = new ListThread(integers);
    ListThread listThread6 = new ListThread(integers);
    ListThread listThread7 = new ListThread(integers);

    listThread1.start();
    listThread2.start();
    listThread3.start();
    listThread4.start();
    listThread5.start();
    listThread6.start();
    listThread7.start();

    listThread1.join();
    listThread2.join();
    listThread3.join();
    listThread4.join();
    listThread5.join();
    listThread6.join();
    listThread7.join();
    
    System.out.println(integers);

显示以下错误:

Exception in thread "Thread-0" java.lang.ArrayIndexOutOfBoundsException: Index 171 out of bounds for length 163
at java.base/java.util.ArrayList.add(ArrayList.java:455)
at java.base/java.util.ArrayList.add(ArrayList.java:467)

问题:据我了解,每个线程都有自己的缓存,每个线程在缓存中都有自己的字段版本integers,列表本身integers存储在 RAM 中。那么这种来自缓存的信息和来自RAM的信息的交互是如何发生的,因为如果一个线程想把一些元素放在数组之外,那么这个数组已经在这个线程的缓存中增加了。如果缓存中有很多变体,那么我们的 RAM 中的列表是如何形成的,哪个变体进入 RAM?

public class ListThread extends Thread {

private final List<Integer> list;

public ListThread(List<Integer> list) {
    this.list = list;
}

@Override
public void run() {
    for (int i = 0; i < 400; i++) {
        list.add(i);
    }
}

}

java
  • 2 2 个回答
  • 31 Views

2 个回答

  • Voted
  1. Best Answer
    Byb
    2023-03-06T22:12:43Z2023-03-06T22:12:43Z

    这里的要点是线程在工作时相互竞争,而ArrayList另一个答案中正确指出的 collection 不是线程安全的。这是您用来添加元素的add()类方法的样子:ArrayList

    public boolean add(E e) {
        modCount++;
        add(e, elementData, size);
        return true;
    }
    

    这就是add()它所依赖的私有方法的样子:

    private void add(E e, Object[] elementData, int s) {
        if (s == elementData.length)
            elementData = grow();
        elementData[s] = e;
        size = s + 1;
    }
    

    线程同时执行公共方法调用add(),这样做会产生各种“意想不到”的效果。可能会或可能不会抛出异常,但并非所有元素都会出现在最终列表中。

    让我们看一下异常。所有线程同时调用add(),后者又调用 private add(),其中不执行块if(首先size小于数组的大小),添加元素并size递增变量。可能会发生所有线程同时增长的情况size,以至于它会跳过elementData.length,超过数组的实际大小。并且下一次调用私有方法时,add()块if仍然不会执行,数组不会扩展,我们将尝试在大于数组大小的索引处添加一个元素,因此异常。

    但是还有一种情况就是上面提到的。add()同时调用而不相互等待的线程通常会用相同的调用它size,因为并非所有add()-s 都起作用,因此不会增加所需的次数。如果程序运行并且没有抛出异常,我们从这里得到相同位置的添加和“劣等”最终列表。

    • 2
  2. CrazyElf
    2023-03-06T21:24:42Z2023-03-06T21:24:42Z

    ArrayList只是不是线程安全的对象。使用线程安全集合来处理来自多个线程的列表,例如英文 CO 中有选项。

    例如,您可以使用Collections.synchronizedList。

    • 0

相关问题

  • wpcap 找不到指定的模块

  • 如何以编程方式从桌面应用程序打开 HTML 页面?

  • Android Studio 中的 R.java 文件在哪里?

  • HashMap 初始化

  • 如何使用 lambda 表达式通过增加与原点的距离来对点进行排序?

  • 最大化窗口时如何调整元素大小?

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5