当前位置: 首页 > 面试题库 >

在没有锁定机制的情况下,通过不同的线程对列表执行读取和“设置”操作是否安全?

施权
2023-03-14
问题内容

遍历List正在由另一个线程执行 添加/删除 操作的,这是非常不安全的。

这就是为什么我们需要 CopyOnWriteArrayList

public static void main(String[] args) throws InterruptedException {
    List<String> list = new ArrayList<>();

    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            while (true) {
                // java.util.ConcurrentModificationException
                for (String s : list) {
                    System.out.println(s);
                }
            }
        }

    });
    thread.start();

    for (int i=0; i<1000; i++) {
        list.add("string" + i);    
    }

    Thread.sleep(Long.MAX_VALUE);
}

但是,如何 设置 操作。当前,以下代码不会引发任何异常。

public static void main(String[] args) throws InterruptedException {
    List<String> list = new ArrayList<>();
    list.add("dummy");

    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            while (true) {
                for (String s : list) {
                    System.out.println(s);
                }
            }
        }

    });
    thread.start();

    for (int i=0; i<1000; i++) {
        list.set(0, "smart");
    }

    Thread.sleep(Long.MAX_VALUE);
}

即使没有任何意外的结果,我也想知道,如果线程仅对执行 设置 操作List,那么我们是否不使用任何锁定机制或copy n
write机制是一种好习惯?


问题答案:

引用以下内容的javadoc
ArrayList

请注意,此实现未同步。如果多个线程同时访问ArrayList实例,并且至少有一个线程在结构上修改列表,则必须在外部进行同步。(结构修改是添加或删除一个或多个元素或显式调整后备数组大小的任何操作;仅
设置元素的值不是结构修改 。)

所以不,它不需要同步。



 类似资料:
  • 问题内容: 我想将实时生产数据库复制到本地开发数据库中。有没有一种方法可以不锁定生产数据库? 我目前正在使用: 但是它在运行时锁定每个表。 问题答案: 该选项有效吗? 根据手册页,如果要转储InnoDB表,则可以使用以下选项: 对于 innodb DB :

  • 我有一个动作执行,其中一个if/fe是如果用户按“A”键,它会将文本设置为不同的内容。程序不是在按“A”后设置文本,而是跳过设置文本并向下移动到下面的if语句。我的问题是,如何让我的程序在我的if语句之前设置文本?我的代码在下面,谢谢!

  • 从这段代码中我可以理解,一个线程一旦进入方法,就获取inst1上的锁,然后获取inst2上的锁,而不释放inst1锁。我假设这两个对象都没有被其他线程锁定。< br> 如果一个线程一次只能获得一个对象的锁,并且在当前对象的锁被释放时只能拥有另一个锁,那么这段代码怎么可能是有效的,或者更确切地说,它是我认为我在某个地方看到的有效代码吗? 如果Type1和Type2是相同的呢? 如果我们使方法同步,考

  • 问题内容: 我有一个没有情节提要的应用程序,所有UI创建都是通过代码完成的,我得到了一个我可以使其在iPhone上使用的应用程序,因为该应用程序最初仅是为iPad设计的,因此当您在列表中选择一行时,大师认为,它在iPhone上什么也不做,但在iPad上工作正常。 所以我的问题是我可以创建并执行允许在方法上显示“详细视图”的segue 吗? 到目前为止,这是我所做的: 但是当运行并选择一行时,应用程

  • 我知道这似乎是一个反复询问和回答的问题,但即使在梳理堆栈溢出数小时后,我仍然无法解决问题。如果我错过了一些明显的东西,请提前向我道歉。 每次线程启动时,我都需要更改JLable的文本,当线程结束时,我需要再次更改JLable的文本。简单地说,我试图显示当前正在运行的线程的数量。 是一个静态的最终JLabel。是具有JLabel的jFrame。是一个静态int。 在每个线程的开始处: 在每个线程的末

  • 目前,我正在研究一个考勤应用程序的可行性,该应用程序具有为Android和iOS编写的以下功能。iOS-不能自动化。每次点击标签时,它都需要用户输入或单击。 然而,我没有很多关于Android NFC功能的谷歌搜索结果。我想在我的考勤应用程序中使用以下功能。 > 将员工ID写入标记或在员工记录中记录标记标识符(使用第三方应用程序) 考勤应用程序将安装和设置在Android手机上,并保存在塑料盒(考