`

SynchronizedList

阅读更多
如何正确使用SynchronizedList?

操作List,已经做了同步synchronized,还会有ConcurrentModificationException,知道为什么吗?


1.

static class SynchronizedList<E>
        extends SynchronizedCollection<E>
        implements List<E> {
        private static final long serialVersionUID = -7754090372962971524L;

        final List<E> list;

        SynchronizedList(List<E> list) {
            super(list);
            this.list = list;
        }
        SynchronizedList(List<E> list, Object mutex) {
            super(list, mutex);
            this.list = list;
        }

        public boolean equals(Object o) {
            if (this == o)
                return true;
            synchronized (mutex) {return list.equals(o);}
        }
        public int hashCode() {
            synchronized (mutex) {return list.hashCode();}
        }

        public E get(int index) {
            synchronized (mutex) {return list.get(index);}
        }
        public E set(int index, E element) {
            synchronized (mutex) {return list.set(index, element);}
        }
        public void add(int index, E element) {
            synchronized (mutex) {list.add(index, element);}
        }
        public E remove(int index) {
            synchronized (mutex) {return list.remove(index);}
        }

        public int indexOf(Object o) {
            synchronized (mutex) {return list.indexOf(o);}
        }
        public int lastIndexOf(Object o) {
            synchronized (mutex) {return list.lastIndexOf(o);}
        }

        public boolean addAll(int index, Collection<? extends E> c) {
            synchronized (mutex) {return list.addAll(index, c);}
        }

        [b]public ListIterator<E> listIterator() {
            return list.listIterator(); // Must be manually synched by user
        }

        public ListIterator<E> listIterator(int index) {
            return list.listIterator(index); // Must be manually synched by user
        }[/b]

    }


static class SynchronizedCollection<E> implements Collection<E>, Serializable {
        private static final long serialVersionUID = 3053995032091335093L;

        final Collection<E> c;  // Backing Collection
        final Object mutex;     // Object on which to synchronize

        [b]SynchronizedCollection(Collection<E> c) {
            this.c = Objects.requireNonNull(c);
            mutex = this;
        }[/b]


2. 可以看出这个类的大多数方法通过同步块实现,
List<User> list = Collections.synchronizedList();
锁为synchronizedList.

3. iterator. stream, parallelStream 多线程操作必须用户自己实现同步
同步方法

package perf;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

public class Test {

	public static void main(String[] args) throws InterruptedException {

		
		List<User> list = Collections.synchronizedList(new ArrayList<User>());
		// lock
		final List<User> mutex = list;

		for (int i = 0; i < 100000; i++) {
			User user = new User();
			user.setName("" + i);
			list.add(user);
		}

		System.out.println("list = " + list.size());

		new Thread(new Runnable() {

			@Override
			public void run() {
				// use lock
				synchronized (mutex) {
					for (Iterator<User> it = list.iterator(); it.hasNext();) {
						User user = it.next();
						if (user.getName().indexOf("9") != -1) {
							it.remove();
						}
					}
				}
			}
		}).start();

		new Thread(new Runnable() {

			@Override
			public void run() {
				// use lock
				synchronized (mutex) {
					for (Iterator<User> it = list.iterator(); it.hasNext();) {
						User user = it.next();
						if (user.getName().indexOf("8") != -1) {
							it.remove();
						}
					}
				}
			}
		}).start();

		Thread.currentThread().sleep(1000L);

		System.out.println("list = " + list.size());
		System.out.println("list = " + list.isEmpty());
	}
}

class User {
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}



分享到:
评论

相关推荐

    Collections.synchronizedList

    标题中的"Collections.synchronizedList"是指Java集合框架中的一个静态工厂方法,用于将任何List转换为线程安全的List。这个方法是Java中实现多线程环境下的集合操作的重要工具,确保在并发访问时数据的一致性和完整...

    java中SynchronizedList和Vector的区别详解

    `SynchronizedList`和`Vector`都是提供线程安全保证的列表实现,但它们在实现方式和性能上存在一些差异。下面我们将深入探讨这两个类的区别。 1. **实现方式** - `Vector` 是 `java.util` 包中的一个类,它直接...

    你知道synchronizedList和Vector底层原理实现和区别吗?其实开始我也不知道!(超详细源码分析)

    疑问:同样都是加了锁的集合,为什么synchronizedList比Vector快呢? 探究ArrayList为什么查询快、增删慢,实现add方法底层原理详解 ArrayList源码分析(基于JDK8) 因为Vector和ArrayList除了数组扩容有点差别,...

    spring-data-mongodb-test:在Collections.synchronizedList或Collections.synchronizedSet上测试spring数据mongodb ConcurrentModificationException

    Spring数据mongodb测试 在Collections.synchronizedList或Collections.synchronizedSet上测试spring数据mongodb ConcurrentModificationException

    Java的线程安全与不安全集合.docx

    2. 使用`Collections.synchronizedList(new ArrayList)`: 这种方法通过装饰器模式,将传入的`ArrayList`包装成`synchronizedList`,对所有调用的方法添加了同步控制。这样在并发环境下,多个线程调用`add()`等方法时...

    java ArrayList和Vector的区别详解

    在实际开发中,如果对线程安全有需求,可以考虑使用Collections.synchronizedList()方法将ArrayList转换为线程安全的列表,或者使用CopyOnWriteArrayList,这是一个更适合并发读写场景的线程安全实现。而如果在单...

    java提高篇(二一)-----ArrayList.pdf

    此外,ArrayList不是线程安全的,如果在多线程环境中使用,需要通过Collections.synchronizedList方法使ArrayList同步。 二、ArrayList源码分析 1. 底层实现:ArrayList的内部字段`elementData`是一个transient的...

    Java集合多线程安全.docx

    2. 使用`Collections.synchronizedList`:这个静态方法可以将给定的`ArrayList`转换为线程安全的列表。在内部,它通过在方法调用上添加`synchronized`关键字来实现同步。这提供了线程安全的访问,但仍然需要谨慎处理...

    10个Java经典的List面试题!.pdf

    因此,如果需要在多线程环境下使用List,应该选择Vector或使用Collections.synchronizedList()方法来将List转换为线程安全的集合。 3.List是有序的吗? 是的,List是有序的。List中元素的顺序是固定的,可以使用...

    java并发编程实战范例(由浅入深代码范例和详细说明)(合集).docx

    2. 使用`Collections.synchronizedList()`:Java标准库提供了同步包装器,将普通集合转换为线程安全的集合,如`List`可以通过`Collections.synchronizedList()`进行转换。 3. 使用`ReentrantLock`:如果需要更细...

    ArrayList的学习821.docx

    为了在多线程环境下安全地使用ArrayList,可以借助`Collections.synchronizedList`方法将其包装成线程安全的列表。例如: ```java List, Object&gt;&gt; test = Collections.synchronizedList(new ArrayList, Object&gt;&gt;())...

    JDKAPI18CN(中文版)

    如果没有这样的对象存在,列表应该使用Collections.synchronizedList方法“包装”。 这最好在创建时完成,以防止意外的不同步访问列表: List list = Collections.synchronizedList(new ArrayList(...)); The ...

    Java软件开发实战 Java基础与案例开发详解 12-5 集合类的同步问题 共8页.pdf

    private List&lt;String&gt; list = Collections.synchronizedList(new ArrayList()); public void run() { synchronized (list) { Iterator&lt;String&gt; iterator = list.iterator(); while (iterator.hasNext()) { ...

    ArrayList.java

    如果该对象不存在,该列表应被“包装”使用Collections.synchronizedList方法。 这最好在创建时完成,以防止意外的名单不同步访问: List list = Collections.synchronizedList(new ArrayList(...)); 此类的返回的...

    java面试问题-java基础相关.docx

    - 使用 `Collections.synchronizedList()`:这个静态工厂方法会返回一个线程安全的 List 实例,它是原有 List 的包装器。例如: ```java List, Object&gt;&gt; data = Collections.synchronizedList(new ArrayList, ...

    2.Java集合-Collection1

    `ArrayList`是非线程安全的,多线程环境下需要通过`Collections.synchronizedList()`来保证安全性。在给定的例子中,如果`A`类的`equals()`方法始终返回`true`,那么`remove(new A())`会删除列表的第一个元素,因为`...

    Java多线程安全集合

    例如,`Collections.synchronizedList`和`Collections.synchronizedMap`。同步集合在每个方法上加锁,确保同一时间只有一个线程可以执行操作。虽然提供了基本的线程安全性,但它们不是高度优化的并发解决方案,因为...

Global site tag (gtag.js) - Google Analytics