如何提高以下java方法从Linkedlist中删除元素的性能

如何提高以下java方法从Linkedlist中删除元素的性能,java,multithreading,performance,Java,Multithreading,Performance,从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)) {

从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";
            }
        }
   }
public void delete(字符串x,链接列表)
{
字符串lock=“false”;
对于(int i=0;i
非常感谢

编辑:上述方法是线程安全的,但其性能需要改进。这是一个面试问题

  • 在方法的本地对象上进行同步实际上没有任何用处。此外,在同步块中覆盖对要锁定的对象的引用在目的上是混乱的。关于该代码用途的一些解释可能会帮助我们改进它:)

  • 实际问题
    get(i)
    remove(i)
    都要求您将列表迭代到位置i。如果使用列表的实际迭代器和迭代器的remove方法,则只需迭代整个列表一次

  • 在方法的本地对象上进行同步实际上没有任何用处。此外,在同步块中覆盖对要锁定的对象的引用在目的上是混乱的。关于该代码用途的一些解释可能会帮助我们改进它:)

  • 实际问题
    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();
        }
    }
    
    public void delete(字符串x,链接列表){
    已同步(列表){
    for(Iterator it=list.Iterator();it.hasNext();)
    如果(it.next()等于(x))it.remove();
    }
    }
    
    但是,你的问题很可能不是线程安全。您在遍历列表时使用了
    list.delete()
    ,得到了
    ConcurrentModificationException
    。如果是这种情况,请随意删除同步块。

    线程安全:

    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();
        }
    }
    
    public void delete(字符串x,链接列表){
    已同步(列表){
    for(Iterator it=list.Iterator();it.hasNext();)
    如果(it.next()等于(x))it.remove();
    }
    }
    

    但是,你的问题很可能不是线程安全。您在遍历列表时使用了
    list.delete()
    ,得到了
    ConcurrentModificationException
    。如果是这种情况,请随意删除同步块。

    尝试对同步集合使用现成的Java Collections API功能

    您还可以使用迭代器删除项。如文件所述:

    如果使用显式迭代器,则必须调用迭代器方法 从同步块内。如果不遵循此建议,可能会导致 导致不确定性行为


    尝试对同步的集合使用现成的Java Collections API功能

    您还可以使用迭代器删除项。如文件所述:

    如果使用显式迭代器,则必须调用迭代器方法 从同步块内。如果不遵循此建议,可能会导致 导致不确定性行为


    我会使用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);
    

    我会使用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);
    
    public void delete(字符串x,链接列表){
    已同步(列表){
    Iterator it=list.Iterator();
    while(it.hasNext()){
    字符串y=it.next();
    如果(x等于(y)){
    it.remove();
    }
    }
    }
    }
    
    公共作废删除(字符串x,链接列表){
    已同步(列表){
    Iterator it=list.Iterator();
    while(it.hasNext()){
    字符串y=it.next();
    如果(x等于(y)){
    it.remove();
    }
    }
    }
    }
    
    公共作废删除(字符串x,链接列表){
    Set target=Collections.singleton(x);
    已同步(列表){
    list.removeAll(目标);
    }
    }
    
    两件事:

  • 在刚刚创建的字符串上进行同步不会产生任何效果(嗯,不完全是这样,因为
    “false”
    是一个内部字符串,所以在
    “false”
    上进行同步的所有代码段都将被同步,但这是一种获得应用程序范围内同步的黑客方法,可能根本不是您想要的)。您应该正在列表上同步。使用列表的每个人都应该在列表上同步。虽然更好的做法是首先使用同步的集合,但在使用代码时不需要显式的
    synchronized
  • removeAll
    通常是从集合中删除一个或多个对象的所有引用的最有效方法。在最坏的情况下,它相当于对集合进行迭代并使用迭代器删除项(这是
    LinkedList
    的情况),但对于某些实现(如
    ArrayList
    ),它会变得更有效
  • public void delete(字符串x,链接列表){
    Set target=Collections.singleton(x);
    已同步(列表){
    list.removeAll(目标);
    }
    }
    
    两件事:

  • 在刚刚创建的字符串上进行同步不会产生任何效果(嗯,不完全是这样,因为
    “false”
    是一个内部字符串,所以在
    “false”
    上进行同步的所有代码段都将被同步,但这是一种获得应用程序范围内同步的黑客方法,可能根本不是您想要的)。你应该
    public void delete(String x, LinkedList<String> list){
        Set<String> target = Collections.singleton(x);
        synchronized (list) {
            list.removeAll( target );
        }
    }