Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use CopyOnWriteArrayList

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly explains "how to use CopyOnWriteArrayList". Interested friends may wish to have a look at it. The method introduced in this paper is simple, fast and practical. Now let the editor take you to learn how to use CopyOnWriteArrayList.

I. A brief analysis of the source code of Vector collection

Since the focus of this article is not on the Vector collection, I simply analyze the initialization method of Vector and the method of adding elements.

The underlying implementation of Vector, like ArrayList, is implemented by arrays.

The main variables of Vector are as follows:

/ * Array of storage elements * / protected Object [] elementData;/** * number of elements * / protected int elementCount;/** * capacity expansion size * / protected int capacityIncrement;1.1 Vector initialization

The initialization of Vector provides three methods. You can specify not only the initial capacity, but also the expansion capacity. The constructors are as follows:

No-parameter constructor

Public Vector () {this (10);}

A constructor that specifies the initialization capacity

Public Vector (int initialCapacity) {this (initialCapacity, 0);}

A constructor that specifies the initialization capacity and expansion capacity

Public Vector (int initialCapacity, int capacityIncrement) {super (); if (initialCapacity

< 0) throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity); this.elementData = new Object[initialCapacity]; this.capacityIncrement = capacityIncrement;} 从上面的构造器中可以看出,如果调用无参构造器,则会创建一个初始化容量为10,扩容容量为0的Vector集合。 1.2 如何扩容 Vector的扩容机制和ArrayList的很像,如果不清楚ArrayList的扩容机制,可以看看这篇文章。这里我们直接看Vector的扩容方法grow。 private void grow(int minCapacity) { // overflow-conscious code // 初始化数组的长度,默认为10 int oldCapacity = elementData.length; // 是否指定扩容容量,不指定扩容为原来的2倍 int newCapacity = oldCapacity + ((capacityIncrement >

0)? CapacityIncrement: oldCapacity); if (newCapacity-minCapacity)

< 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE >

0) newCapacity = hugeCapacity (minCapacity); elementData = Arrays.copyOf (elementData, newCapacity);}

Through the above method, we can see that if you specify the size of the expansion capacity, the size of the new array will be the original array plus the size of the capacity, and if you do not specify the size of the capacity, the size of the new array will be twice the size of the original array. This expansion of twice the original capacity consumes a lot of space, which is one of the reasons why Vector is abandoned.

In addition, students who have read the source code may have found that all the operation elements of the Vector collection have added the synchronized keyword, which leads to a very low efficiency of operating Vector. In development, read operations are often used much more frequently than other operations, and CopyOnWriteArrayList is such a read operation that is much more efficient than write operations. Let's take a look.

II. Brief Analysis of CopyOnWriteArrayList Source Code

CopyOnWriteArrayList class diagram:

2.1 CopyOnWrite thought

CopyOnWrite is abbreviated to COW, which, according to the name, is copied on write. It means that everyone accesses a resource together. if someone wants to modify the resource, they need to make a copy and modify the copy, but for others, the access to the resource is the same and will not change.

2.2 initialize CopyOnWriteArrayList

The underlying layer of CopyOnWriteArrayList is also implemented by arrays. In this article, we only interpret the difference between adding elements and reading elements. the principle of deleting and modifying elements is similar to that of adding elements. both operations need to be locked, but read operations will not be locked.

CopyOnWriteArrayList has the following two main variables:

/ / exclusive lock final transient ReentrantLock lock = new ReentrantLock (); / / Array private transient volatile Object [] array that stores elements

Let's take a closer look at the above two attributes, which are at the core of CopyOnWriteArrayList.

Lock:ReentrantLock, exclusive lock, in the case of multithreaded running, only one thread will acquire the lock, and other threads can only acquire it after releasing the lock.

Array: the key to storing the array of data is that it is decorated by volatile and volatile to ensure visibility, that is, after one thread is modified, other threads are immediately visible.

The most common initialization methods are as follows:

/ * Creates an empty list. * / public CopyOnWriteArrayList () {setArray (new Object [0]);} / * * Sets the array. * / final void setArray (Object [] a) {array = a;}

Initialization simply creates an empty array and points array to it.

2.3 add the element public boolean add (E e) {final ReentrantLock lock = this.lock; lock.lock (); try {/ / get the original array Object [] elements = getArray (); / / the length of the original array int len = elements.length / / create a new array of length + 1 and copy the elements of the original array to the new array Object [] newElements = Arrays.copyOf (elements, len + 1); / / the element is placed at the end of the new array newElements [len] = e; / / array points to the new array setArray (newElements); return true;} finally {lock.unlock ();}}

The steps to add an array are:

Get the exclusive lock and add the lock to the function

Get the original array and get its length

Create an array with the length of the original array + 1, and copy the original elements to the new array

Append elements to the end of the new array

Point to the new array

Release lock

This process is thread-safe, the core idea of COW is to copy a new resource to modify each time, and the add () method will add 1 to the capacity of the array when copying the new resource, so that although a certain amount of space is wasted every time an element is added, the length of the array is exactly the length of the element, which saves the cost of expansion to a certain extent.

2.4 get the element public E get (int index) {return get (getArray (), index);} final Object [] getArray () {return array;} private E get (Object [] a, int index) {return (E) a [index];}

The read operation is naturally safe, and the array itself checks for out-of-bounds problems, so the way to get the element is simple, just get the element according to the index.

Public int size () {return getArray () .length;}

Because the underlying array length of CopyOnWriteArrayList is itself the element size, the size () method simply returns the array length.

At this point, I believe you have a deeper understanding of "how to use CopyOnWriteArrayList". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report