java 数组列表上的易失性/同步

2024-03-26

我的程序如下所示:

public class Main {
    private static ArrayList<T> list;

    public static void main(String[] args) {
        new DataListener().start();
        new DataUpdater().start();
    }

    static class DataListener extends Thread {
        @Override
        public void run() {
            while(true){
                //Reading the ArrayList and displaying the updated data
                Thread.sleep(5000);
            }
        }
    }

    static class DataUpdater extends Thread{
        @Override
        public void run() {
            //Continuously receive data and update ArrayList;
        }
    }
}

为了在两个线程中使用这个ArrayList,我知道有两个选择:

  1. 使 ArrayList 易失。然而我读到本文 http://www.ibm.com/developerworks/java/library/j-jtp06197/index.html仅当“写入变量不依赖于其当前值”时才允许使变量变为易失性。我认为在这种情况下确实如此(因为例如当您对 ArrayList 执行添加操作时,此操作后 ArrayList 的内容取决于 ArrayList 的当前内容,或者不是吗?)。此外,DataUpdater 必须时不时地从列表中删除一些元素,而且我还读到从不同线程编辑易失性变量是不可能的。

  2. 使这个 ArrayList 成为同步变量。但是,我的DataUpdater会不断更新ArrayList,那么这不会阻止DataListener读取ArrayList吗?

我是否误解了这里的任何概念,或者是否有其他选择可以实现这一点?


挥发性根本不会帮助你。的含义volatile线程 A 对共享变量所做的更改对线程 B 立即可见。通常,此类更改可能在某些缓存中仅对进行更改的线程可见,并且volatile只是告诉 JVM 不要进行任何会导致值更新延迟的缓存或优化。

所以它不是一种同步手段。这只是确保变革可见性的一种手段。此外,它的变化是variable,不至于该变量引用的对象。也就是说,如果您标记list as volatile,只有当你分配一个新列表给list,如果您更改列表的内容则不会!


你的另一个建议是ArrayList同步变量。这里有一个误解。变量无法同步。唯一可以同步的是code- 整个方法或其中的特定块。您使用一个对象作为同步监视器.

监视器是对象本身(实际上,它是监视器对象的逻辑部分),而不是变量。如果在同步旧值后将不同的对象分配给同一变量,则旧监视器将不可用。

但无论如何,同步的不是对象,而是您决定使用该对象同步的代码。

因此,您可以使用list作为同步其上操作的监视器。但你不能拥有list同步。


假设您想使用列表作为监视器来同步您的操作,您应该对其进行设计,以便编写器线程不会始终持有锁。也就是说,它只是抓取它进行一次读取更新、插入等,然后释放它。再次抓住它以进行下一次操作,然后释放它。如果同步整个方法或整个更新循环,其他线程将永远无法读取它。

在阅读线程中,你可能应该这样做:

List<T> listCopy;

synchronized (list) {
    listCopy = new ArrayList(list);
}

// Use listCopy for displaying the value rather than list

这是因为显示可能很慢 - 它可能涉及 I/O、更新 GUI 等。因此,为了最小化锁定时间,您只需从列表中复制值,然后释放监视器,以便更新线程可以完成其工作。


除此之外,还有很多类型的对象java.util.concurrent包等旨在帮助解决此类情况,其中一侧正在写入,另一侧正在读取。检查文档 - 也许是ConcurrentLinkedDeque会为你工作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java 数组列表上的易失性/同步 的相关文章

随机推荐