java - 如何确保传递给方法的集契约(Contract)步?

标签 java android multithreading

我在一个内部类上有以下方法,我用它来对多线程应用程序中的多个集合进行排序。我想确保每个集合在排序时都是同步的(我已经在我迭代的其他地方同步了)。

注意:其中一个集合支持 ListView 的适配器。

private void sort(List<...> collection) {
    if (collection != null) {
        Collections.sort(collection, ...);
    }
}

问题是如果我包装 synchronised(collection) { Collections.sort } IDE 警告我同步方法参数是不安全的。

我知道这是一个新引用,但该引用仍然指向原始集合,这样安全吗?如果没有,有没有办法测试集合是否被锁定? (所以我可以在误用时抛出异常)

最佳答案

我认为这里的问题是应该如何访问这些集合。 例如,如果您想要多次读取并且只有一个写入线程到集合中,您应该使用包装类和 ReentrantReadWriteLock:

public class ListWrapper {

    private final ArrayList<String> theList = new ArrayList<String>();
    private final ReadWriteLock rwl = new ReentrantReadWriteLock();
    private final Lock r = rwl.readLock();
    private final Lock w = rwl.writeLock();    

    public String read() {
        r.lock();
        try {
            System.out.println("reading");
            if(theList.isEmpty()) {
                return null;
            }
            else {
                return theList.get(0);
            }
        } finally {
            r.unlock();
        }
    }

    public void write(String data) {
        w.lock();
        try {
            System.out.println("Written " + data);
            theList.add(data);
        } finally{
            w.unlock();
        }
    }
}

与内部有列表但不直接公开列表的包装类相同。

public class ListWrapper {    
    private final List<String> obj;     
    public ListWrapper (Object obj) { 
        this.obj = obj; 
    }     

    public List<String> getList() { 
        return obj; 
    } 
}

上面的类是线程安全的,因为它不对被包装的对象进行任何操作。 类包装的对象可能是线程安全的,也可能不是线程安全的,因为返回包装对象的引用后,多个线程可以对该对象进行操作。

因此,被包装对象本身是否线程安全取决于被包装对象的类是如何实现的。

你也可以使用

CopyOnWriteArrayList

其中是 ArrayList 的线程安全变体,其中所有可变操作都是通过制作底层数组的新副本来实现的。

我认为这取决于实现。

关于java - 如何确保传递给方法的集契约(Contract)步?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43191011/

相关文章:

java - SWT 可编辑组合 - 突出显示文本

android - 开发 Android 主屏幕

c++ - 是否加入 std::thread 刷新内存?

vb.net - 无法从另一个线程向 DataTable 添加行

java - 迭代对象列表并跳过一个索引并稍后再次读取它

java - 自定义检查组合框

Android Studio - 扩展类 com.google.ads.AdView 时出错

java - 两次启动另一个 Activity 时,线程不更新 textview

Javafx:从 ScheduledService 检索 observableList 各个元素并将它们分别绑定(bind)到不同的属性

android - AuthException 未解析为类型和多个 dex 文件 - 构建路径