[英]how to improve the performance of the following java method to delete elements from a Linkedlist
一种从链表删除节点的线程安全方法。
public void delete(String x, LinkedList<String> list)
{
String lock = "false";
for (int i = 0; i < list.size(); i++) {
synchronized (lock) {
if (list.get(i).equals(x)) {
lock = "true";
list.remove(i);
}
lock = "false";
}
}
}
非常感谢!
编辑:上面的方法是线程安全的,但其性能需要提高。 这是一个面试问题。
在方法本地的对象上进行同步实际上并没有做任何有用的事情。 另外,覆盖对您在同步块内锁定的对象的引用,在目的上会造成混淆。 关于该代码的目的的一些解释可能会帮助我们帮助您改进它:)
实际的问题。 get(i)
和remove(i)
都需要您迭代列表以将其定位到i。 如果使用列表的实际迭代器和迭代器的remove方法,则只需要迭代整个列表一次。
线程安全的:
public void delete(String x, LinkedList<String> list) {
synchronized (list) {
for (Iterator<String> it = list.iterator(); it.hasNext();)
if (it.next().equals(x)) it.remove();
}
}
但是,很可能您的问题不是线程安全。 您在遍历列表时使用了list.delete()
并获得了ConcurrentModificationException
。 在这种情况下,请随时删除同步块。
我会用List.removeAll
List<String> list = new LinkedList<>();
list.addAll(Arrays.asList("a,b,c,d,a,b,c,d,e,a,b,a,b".split(",")));
System.out.println("Before removeAll(a) " + list);
list.removeAll(Collections.singleton("a"));
System.out.println("After removeAll " +list);
版画
Before removeAll(a) [a, b, c, d, a, b, c, d, e, a, b, a, b]
After removeAll [b, c, d, b, c, d, e, b, b]
尝试对同步集合使用开箱即用的Java集合API功能。 官方文件。
而且,您还可以使用迭代器删除项目。 如文档所述:
如果使用显式迭代器,则必须从同步块内调用迭代器方法。 不遵循该建议可能导致不确定的行为。
public void delete (String x, LinkedList<String> list) {
synchronized (list) {
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String y = it.next();
if (x.equals(y)) {
it.remove();
}
}
}
}
public void delete(String x, LinkedList<String> list){
Set<String> target = Collections.singleton(x);
synchronized (list) {
list.removeAll( target );
}
}
两件事情:
"false"
是一个内部字符串,所有在"false"
进行同步的代码段都将被同步,但这是获得应用程序范围内同步的一种不可靠的方式,可能根本没有您的意图)。 您应该在列表上进行同步。 使用列表的每个人都应该在列表上进行同步。 尽管更好的做法是首先使用同步集合,但在使用代码中无需显式synchronized
块。 removeAll
通常是从集合中删除所有出现的一个或多个对象的最有效方法。 在最坏的情况下,这等效于遍历集合并使用迭代器删除项目(在LinkedList
的情况下),但是对于某些实现(例如ArrayList
),这样做使其效率更高。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.