Home >Java >javaTutorial >java concurrent programming (4) performance and scalability

java concurrent programming (4) performance and scalability

巴扎黑
巴扎黑Original
2017-06-26 09:14:181481browse

Performance and Scalability

1. Amdahl’s Law

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

2. Thread overhead

Since multi-threading has Overhead: Therefore, the use of multi-threading must ensure performance improvement>Concurrency overhead

Context switching overhead

Memory synchronization overhead

3. Reduce lock competition

 1. Reduce the lock holding time: reduce the scope of the lock

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);
    }

 2. Reduce the frequency of lock requests: lock decomposition and lock segmentation. ..

  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;
            }
        }
    }
}

3. Avoid hot spots

Performance problems caused by fierce lock competition for hot resources

4 .Replace exclusive locks

 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.

 5. Reduce context Switching

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!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn