置頂 0%

Which collections classes are thread-safe in Java

Currently, I've been preparing for interview questions related to Java, and I find thread-safe Collections classes quite interesting. This is because I encountered a similar question related to Collections in a previous job interview. I would say that Collections is one of the most popular topics that interviewers like to ask about.

Thread-safe Collections

Not Thread-safe code sample

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class ConcurrentExample {
private void test() {
Integer num = 1300;
arrayList.add(num);
System.out.println("Before Loop" + this.getClass());

for(int i=0;i<1000000000;i++) continue;
System.out.println("After Loop" + this.getClass());

System.out.println("final" + this.arrayList);
arrayList.remove(num);
}
public static void main(String[] args) {
ConcurrentExample concurrentExample = new ConcurrentExample();
Runnable runnableA = new Runnable() {
@Override
public void run() {
concurrentExample.test();
}
};

Runnable runnableB = new Runnable() {
@Override
public void run() {
concurrentExample.test();
}
};
Thread threadA = new Thread(runnableA);
Thread threadB = new Thread(runnableB);

threadA.start();
threadB.start();
}
}

Above code will cause a unexpectable result due to multi-threading. So we can use the following ways to avoid this issue.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// method 1
private ArrayList<Integer> arrayList = new ArrayList();
private void test() {
Integer num = 1300;
synchronized (arrayList) {
arrayList.add(num);
for(int i=0;i<1000000000;i++) continue;
arrayList.remove(num);
}
}

// method 2
private ArrayList<Integer> arrayList = Collections.synchronizedList(new ArrayList<>());
private void test() {
Integer num = 1300;
arrayList.add(num);
for(int i=0;i<1000000000;i++) continue;
arrayList.remove(num);
}

Thread-safe collections, such as the following examples, ensure safe concurrent access to data

  1. ConcurrentHashMap
  2. SynchronizedHashMap
  3. Stack
  4. Vector
  5. CopyOnWriteArrayList
  6. CopyOnWriteArraySet
  7. HashTable

Add element in List while iterating

First of all, how to add element in List while iterating in java?

1
2
3
4
5
6
7
8
9
10
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
for(String s : new ArrayList<>(list)) {
if(s.equals("a")) {
list.add("z");
}
System.out.println(s);
}

Above code will throw a ConcurrentModificationException which is used to fail-fast when we try to iterate and modify at the same time. So we can use the following substitue ways to do the smae thing.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");

// method 1
ListIterator<String> iterator = list.listIterator();
while(iterator.hasNext()) {
String next = iterator.next();
if(next.equals("a")) {
iterator.add("z");
}
System.out.println(next);
}

// method 2
for(String s : new ArrayList<>(list)) {
if(s.equals("a")) {
list.add("z");
}
System.out.println(s);
}

// method 3
int size = list.size();
for(int i=0;i<size;i++) {
String s = list.get(i);
if(s.equals("a")) {
list.add("z");
}
System.out.println(s);
}