Conteúdo do Curso
Multithreading in Java
Multithreading in Java
Examples of Using Collections Methods
Note
Today we will mainly look at methods that help to create thread-safe collections.
Collections Methods
Here are some important methods provided by the class to create synchronized Collections
collections:
synchronizedList(List<T> list)
: Returns a synchronized (thread-safe) list that supports the same contract as the passed list.
Main
List<Object> listSync = Collections.synchronizedList(new ArrayList<>());
synchronizedSet(Set<T> set)
: Returns a synchronized (thread-safe) set that supports the same contract as the passed set.
Main
Set<Object> setSync = Collections.synchronizedSet(new HashSet<>());
synchronizedMap(Map<K, V> m)
: Returns a synchronized (thread-safe) map that supports the same contract as the passed map.
Main
Map<Object, Object> mapSync = Collections.synchronizedMap(new HashMap<>());
unmodifiableList(List<? extends T> list)
: Returns an immutable list containing the same elements as the specified list.
Main
package com.example; import java.util.Collections; import java.util.List; import java.util.ArrayList; public class Main { public static void main(String[] args) { List<Integer> unmodifiableList = Collections.unmodifiableList(new ArrayList<>(List.of(1,2,3))); System.out.println(unmodifiableList); // output [1,2,3] unmodifiableList.add(4); // throw exception `UnsupportedOperationException` } }
unmodifiableMap(Map<? extends K, ? extends V> m)
: Returns an immutable map containing the same mappings as the specified map.
Main
package com.example; import java.util.Collections; import java.util.Map; import java.util.HashMap; public class Main { public static void main(String[] args) { Map<Integer, Integer> unmodifiableMap = Collections.unmodifiableMap(new HashMap<>()); unmodifiableMap.put(1, 2); // exception `UnsupportedOperationException` } }
unmodifiableSet(Set<? extends T> set)
: Returns an immodifiable set containing the same elements as the specified set.
Main
package com.example; import java.util.Collections; import java.util.Set; import java.util.HashSet; public class Main { public static void main(String[] args) { Set<Integer> unmodifiableSet = Collections.unmodifiableSet(new HashSet<>()); unmodifiableSet.add(4); // exception `UnsupportedOperationException` } }
What then is the difference between creating synchronized collections through normal implementations (those discussed in the previous chapters) and using Collections
methods?
Let's look at the difference using one Map
collection as an example
Differences between using ConcurrentHashMap and synchronizedMap()
ConcurrentHashMap
employs an advanced method known as lock splitting, which divides the map into segments and synchronizes operations only at the segment level. This approach enables multiple threads to simultaneously read and write data across different segments of the map, improving concurrency and performance.
The method synchronizedMap()
wraps the original map into a synchronized proxy object. All methods of this proxy object are synchronized, ensuring thread-safety. However, this approach can reduce performance in a multithreaded environment due to the high locking frequency involved.
For example, if ConcurrentHashMap
writes to different buckets, the threads will not block each other. However, if one bucket is accessed by 2 threads, one of them will wait. On the other hand, if the collection is created via synchronizedMap()
, only 1 thread will have access to all buckets, and the entire map is blocked.
This means that until one thread finishes its work, other threads will not be able to enter. As a result, operations in ConcurrentHashMap
are simply executed faster.
Also in Collections there are Other Methods for Convenient Work with Collections:
Note
The
Collections
class provides convenient methods for working with collections in Java, simplifying commonly used operations. Synchronized collections created viaCollections
methods are useful for thread safety, but for more complex multithreaded tasks, it is better to use collections from thejava.util.concurrent
package.
Obrigado pelo seu feedback!