1. The relationship between problems and resources
In some problems, the more resources, the faster the solution ; Some problems are the opposite:
Note: Every program must have a serial part, and the impact of the serial and parallel parts on the program should be reasonably analyzed Extremely large; there is an exponential relationship between the proportion of the serial part and multi-core execution efficiency
2.ConcurrentLinkedQueue
In a multi-core environment, this thread-safe queue is faster than the queue generated through synchronizedList The speed is much faster
It can be said that the classes provided in concurrent are faster than the thread-safe classes generated by methods
Since multi-threading has Overhead: Therefore, the use of multi-threading must ensure performance improvement>Concurrency overhead
Context switching overhead
Memory synchronization overhead
private final Map<String, String> attributes = new HashMap<String, String>();//整个方法上锁public synchronized boolean userLocationMatches(String name, String regexp) { String key = "users." + name + ".location"; String location = attributes.get(key);if (location == null)return false;elsereturn Pattern.matches(regexp, location); }public boolean userLocationMatches(String name, String regexp) { String key = "users." + name + ".location"; String location;//只针对可变状态上锁synchronized (this) { location = attributes.get(key); }if (location == null)return false;elsereturn Pattern.matches(regexp, location); }
Lock decomposition: Decompose a lock into multiple locks. For example: there is no need to update multiple state variables in an atomic operation, but each state variable uses the same class lock, which is not necessary. Just use its own lock for each irrelevant state variable
public class ServerStatusBeforeSplit {public final Set<String> users;public final Set<String> queries;public ServerStatusBeforeSplit() { users = new HashSet<String>(); queries = new HashSet<String>(); }//每个方法使用 当前class实例锁,类似于synchronized(this),不管是否是操作同一共享状态public synchronized void addUser(String u) { users.add(u); }public synchronized void addQuery(String q) { queries.add(q); }public synchronized void removeUser(String u) { users.remove(u); }public synchronized void removeQuery(String q) { queries.remove(q); } }public class ServerStatusAfterSplit {public final Set<String> users;public final Set<String> queries;//操作同一 状态的方法 使用相同的锁public ServerStatusAfterSplit() { users = new HashSet<String>(); queries = new HashSet<String>(); }public void addUser(String u) {synchronized (users) { users.add(u); } }public void addQuery(String q) {synchronized (queries) { queries.add(q); } }public void removeUser(String u) {synchronized (users) { users.remove(u); } }public void removeQuery(String q) {synchronized (users) { queries.remove(q); } } }
Lock segmentation: For example, divide the map bucket into different segments , each segment has a lock. In this way, when performing certain operations such as get, you can hold different locks to improve concurrency efficiency. Of course, some operations need to hold the locks of all segments of the container at the same time, such as clear, etc.
//Map分段锁实现public class StripedMap {// Synchronization policy: buckets[n] guarded by locks[n%N_LOCKS]private static final int N_LOCKS = 16; //锁数量private final Node[] buckets; //容器桶private final Object[] locks; //同步监听器对象数组private static class Node { Node next; Object key; Object value; }public StripedMap(int numBuckets) { buckets = new Node[numBuckets]; locks = new Object[N_LOCKS];for (int i = 0; i < N_LOCKS; i++) locks[i] = new Object(); }private final int hash(Object key) {return Math.abs(key.hashCode() % buckets.length); }public Object get(Object key) {int hash = hash(key);//获取当前 key对应的index区域的锁,只获取了一个锁synchronized (locks[hash % N_LOCKS]) {for (Node m = buckets[hash]; m != null; m = m.next)if (m.key.equals(key))return m.value; }return null; }public void clear() {for (int i = 0; i < buckets.length; i++) {//获取 每个i对应的锁,就是获取了整个容器所有的分段锁synchronized (locks[i % N_LOCKS]) { buckets[i] = null; } } } }
Performance problems caused by fierce lock competition for hot resources
For example: read-write lock: reading and reading can be parallelized to prevent exclusive use; use atomic state quantities; use concurrent containers; use immutable objects, etc.
Task switching between blocking and non-blocking states is similar to a context switch
For example: log, log printing and IO operations will cause a lot of blocking and release, resulting in poor performance question
The above is the detailed content of java concurrent programming (4) performance and scalability. For more information, please follow other related articles on the PHP Chinese website!