我正在使用
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是否是线程安全的并且像我在这里一样在其中添加?
对不起,如果这些问题非常基础,我是这个主题的新手,并且没有在互联网上找到答案。 谢谢!!
答案 0 :(得分:1)
for循环实际上是否使用迭代器是正确的,因此我必须使用synchronized包装for?
您的问题分为两部分。
首先,不,你在这里没有使用迭代器,这是一个基本的for循环。
增强的for循环是使用迭代器的for循环:
for (T element : list) { ... }
你可以看到in the language spec它如何使用迭代器 - 搜索它所说的位置&#34;增强的for语句等同于表格的基本for语句&#34;。
其次,即使您没有使用迭代器, 也需要synchronized
。两者是正交的。
您正在执行多项操作(size
,get
和add
),并且它们之间存在依赖关系。您需要确保没有其他线程干扰您的逻辑:
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)。