将synchronizedList与for循环一起使用并在其中添加项目

时间:2017-06-19 07:31:07

标签: java multithreading synchronization thread-safety

我正在使用

Collections.synchronizedList(new ArrayList<T>())

部分代码是:

list = Collections.synchronizedList(new ArrayList<T>());

public void add(T arg) {
    int i;
    synchronized (list) {
        for (i = 0; i < list.size(); i++) {
            T arg2 = list.get(i);

            if (arg2.compareTo(arg) < 0) {
                list.add(i, arg);
                break;
            }

        }

for循环实际上是否使用迭代器是正确的,因此我必须同步包装for?

使用synchronized是否是线程安全的并且像我在这里一样在其中添加?

对不起,如果这些问题非常基础,我是这个主题的新手,并且没有在互联网上找到答案。 谢谢!!

2 个答案:

答案 0 :(得分:1)

  

for循环实际上是否使用迭代器是正确的,因此我必须使用synchronized包装for?

您的问题分为两部分。

首先,不,你在这里没有使用迭代器,这是一个基本的for循环。

增强的for循环是使用迭代器的for循环:

for (T element : list) { ... }

你可以看到in the language spec它如何使用迭代器 - 搜索它所说的位置&#34;增强的for语句等同于表格的基本for语句&#34;。

其次,即使您没有使用迭代器, 也需要synchronized。两者是正交的。

您正在执行多项操作(sizegetadd),并且它们之间存在依赖关系。您需要确保没有其他线程干扰您的逻辑:

  • get取决于size,因为您不想尝试使用index >= size获取元素,例如;
  • add取决于get,因为您显然是在尝试确保列表元素是有序的。如果另一个线程可以潜入并在get之后更改元素,则可能会将新元素插入错误的位置。

通过list的同步创建synchronizedList,正确地避免了这种潜在的干扰,除了synchronizedList之外的任何其他内容都可以获得直接访问基础列表。

答案 1 :(得分:1)

如果你的arg2.compareTo(arg)永远不会返回0(零),你可以使用TreeSet。会更简单:

const arr = [
  { total: 20, name: 'David' },
  { total: 10, name: 'Joe' },
  { total: 15, name: 'Tracy' },
  { total: 20, name: 'Joel' },
  { total: 15, name: 'Michael' },
  { total: 10, name: 'Arnold' },
  { total: 15, name: 'Paul' },
];

// Enter keys by sort order. Key values are -1 for descending and 1 for ascending.
const sortObject = {
  total: -1,
  name: 1,
};

// Get the keys of sortObject.
const sortKeys = Object.keys(sortObject);

const sortedArray = arr.sort((a, b) => {
  let sorted = 0;
  let index = 0;

  // Loop until sorted or until the sort keys have been processed.
  while (sorted === 0 && index < sortKeys.length) {
    const key = sortKeys[index];
    const sortDirection = sortObject[key];

    if (a[key] === b[key]) { // If the values are the same, do not change positions.
      sorted = 0;
    } else { // Switch positions if necessary. If b[key] > a[key], multiply by -1 to reverse directions.
      sorted = a[key] > b[key] ? sortDirection : -1 * sortDirection;
    }

    index++;
  }

  return sorted;
});

console.log(sortedArray);

如果您需要持有相同的项目(compareTo返回0),请使用列表:

set = Collections.synchronizedSet(new TreeSet<T>());

public void add(T arg) {
    set.add(arg);
}

第一和第二种情况复杂性将是log(N)(1000个项目为10)。您的代码复杂度为N(1000个项目为1000)。