Implementation of variable size arrays of List interface. All optional list operations are implemented and all elements including null are allowed. In addition to implementing the List interface, this class also provides some methods to manipulate the size of the array used to store the list internally. (This class is roughly equivalent to the Vector class, except that this class is out of sync.) The size, isEmpty, get, set, iterator, and listIterator operations all run at a fixed time. The add operation runs at a shared fixed time, that is, adding n elements takes O(n) time. All other operations run in linear time (in general). This implementation has a lower constant factor than the constant factor used for the LinkedList implementation. Each ArrayList instance has a capacity. This capacity refers to the size of the array used to store list elements. It is always at least equal to the size of the list. As elements are constantly added to the ArrayList, their capacity also increases automatically. Details of the growth strategy are not specified, because it is not just as simple as adding elements that will result in a fixed time overhead. Before adding a large number of elements, the application can use the ensureCapacity operation to increase the capacity of the ArrayList instance. This can reduce the number of incremental redistributions.
Note that this implementation is not synchronous.
If multiple threads access an ArrayList instance at the same time, and at least one of the threads structurally modify the list, it must remain externally synchronized. (Structural modification refers to any operation of adding or removing one or more elements, or explicitly adjusting the size of the underlying array; setting the value of the element is not a structural modification.) This is generally done by synchronizing objects that naturally encapsulate the list. If such an object does not exist, the list should be "wrapped" using the Collections.synchronizedList method. This is best done at creation time to prevent unexpected access to the list from being synchronized:
Listlist=Collections.synchronizedList(newArrayList(...));
The iterator returned by the iterator and listIterator methods of this class fail quickly: after creating the iterator, unless the list is modified from the structurally by the iterator's own remove or add method, the iterator will throw a ConcurrentModificationException at any time and any way to modify the list. Therefore, in the face of concurrent modifications, the iterator will soon fail completely, rather than risking arbitrary uncertain behavior at some uncertain time in the future.
Note that the fast failure behavior of the iterator cannot be guaranteed, because generally, it is impossible to make any hard guarantees on whether there is an out-of-synchronous concurrent modification. The fast-failed iterator will do its best to throw a ConcurrentModificationException. Therefore, it is wrong to write a program that depends on this exception to improve the correctness of such iterators: the fast failure behavior of the iterator should be used only to detect bugs.
As shown above, now create a list collection, one thread writes the collection, and one thread deletes the collection
import java.util.ArrayList;import java.util.Collections;import java.util.Iterator;import java.util.List;import java.util.Random;public class MyArrayList {/** * Create a list, a thread writes, and a thread reads the iterator and listIterator methods. The iterator returned by the method is fast.*/public void readWrite() {List<Integer> nums = new ArrayList<Integer>();List<Integer> synNums = Collections.synchronizedList(nums);//Start the write thread new WriteListThread(syncNums).start();//Start the delete thread new DeleteListThread(syncNums).start();}public static void main(String[] args) {new MyArrayList().readWrite();}}class WriteListThread extends Thread {private List<Integer> nums;public WriteListThread(List<Integer> nums) {super("WriteListThread"); this.nums = nums;}// Keep writing element 1 public void run() {while (true) {nums.add(new Random().nextint(1000));System.out.println(Thread.currentThread().getName());}}}class DeleteListThread extends Thread {private List<Integer> nums;public DeleteListThread(List<Integer> nums) {super("DeleteListThread");this.nums = nums;}// Delete the first element public void run() {while (true) {try{System.out.println(Thread.currentThread().getName()+":"+nums.remove(0));}catch(Exception e){continue ;}}}}The atomic operations can be synchronized by List<Integer>syncNums=Collections.synchronizedList(nums); but why do you need to manually add synchronization by the official API example?
List list = Collections.synchronizedList(new ArrayList()); synchronized(list) { Iterator i = list.iterator(); // Must be in synchronized block while (i.hasNext()) foo(i.next()); }View the source code of Collections.synchronizedList
SynchronizedCollection(Collection<E> c) { if (c==null) throw new NullPointerException(); this.c = c; mutex = this; } import java.util.ArrayList;import java.util.Collections;import java.util.Iterator;import java.util.List;import java.util.Random;public class MyArrayList {/** * Create a list, a thread writes, and a thread reads the iterator and listIterator methods. The iterator returned by the method is fast.*/public void readWrite() {List<Integer> nums = new ArrayList<Integer>();List<Integer> synNums = Collections.synchronizedList(nums);//Start the write thread new WriteListThread(syncNums).start();//Start the delete thread new DeleteListThread(syncNums).start();}public static void main(String[] args) {new MyArrayList().readWrite();}}class WriteListThread extends Thread {private List<Integer> nums;public WriteListThread(List<Integer> nums) {super("WriteListThread"); this.nums = nums;}// Keep writing element 1 public void run() {while (true) {nums.add(new Random().nextint(1000));System.out.println(Thread.currentThread().getName());}}}class DeleteListThread extends Thread {private List<Integer> nums;public DeleteListThread(List<Integer> nums) {super("DeleteListThread");this.nums = nums;}// Delete the first element public void run() {while (true) {try{System.out.println(Thread.currentThread().getName()+":"+nums.remove(0));}catch(Exception e){continue ;}}}}It can be seen that for collection synchronization operations, using the synchronization wrapper tool class of Collections, users need to manually synchronize non-atomic operations.
As shown below, add a thread to read the collection
class ReadListThread extends Thread {private List<Integer> nums;public ReadListThread(List<Integer> nums) {super("ReadListThread");this.nums = nums;}// Keep reading of elements and non-atomic operations, you need to manually add a lock public void run() {while (true) {//Sleep, hand the lock to other threads try {Thread.sleep(1000);}catch (InterruptedException e1) {e1.printStackTrace();}synchronized (nums) {if (nums.size() > 100) {Iterator<Integer> iter = nums.iterator();while (iter.hasNext()) {System.out.println(Thread.currentThread().getName() + ”:” + iter.next());;}} else{try {nums.wait(1000);}catch (InterruptedException e) {e.printStackTrace();}}}}}}}}Summarize
The above is all the detailed explanation of the thread synchronization code of this article about the Java collection framework, and I hope it will be helpful to everyone. Interested friends can continue to refer to other related topics on this site. If there are any shortcomings, please leave a message to point it out. Thank you friends for your support for this site!