Java 高并发下的实践
一、使用的技术
HashMap
ConcurrentHashMap
Lock
ReadWriteLock
synchronized
二、一百万并发下的组合
ConcurrentLockMap
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package cn.edu.scau.mk.map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * * @author MK */ public class ConcurrentLockMap implements In { ConcurrentHashMap<Integer, Integer> map = new ConcurrentHashMap<>(); Lock lock = new ReentrantLock(); @Override public void add(int a) { lock.lock(); try { if (map.containsKey(a)) { map.put(a, 1 + map.get(a)); } else { map.put(a, 1); } } finally { lock.unlock(); } } @Override public int get(int a) { int as = map.get(a); return as; } }
ConcurrentSynchronizedMap
package cn.edu.scau.mk.map; import java.util.concurrent.ConcurrentHashMap; /** * * @author MK */ public class ConcurrentSynchronizedMap implements In { ConcurrentHashMap<Integer, Integer> map = new ConcurrentHashMap<>(); @Override public void add(int a) { synchronized ((""+a).intern()) { if (map.containsKey(a)) { map.put(a, 1 + map.get(a)); } else { map.put(a, 1); } } } @Override public int get(int a) { int as = map.get(a); return as; } }
LockHashMap
package cn.edu.scau.mk.map; import java.util.HashMap; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * * @author MK */ public class LockHashMap implements In { HashMap<Integer, Integer> map = new HashMap<>(); Lock lock = new ReentrantLock(); @Override public void add(int a) { lock.lock(); try { if (map.containsKey(a)) { map.put(a, 1 + map.get(a)); } else { map.put(a, 1); } } finally { lock.unlock(); } } @Override public int get(int a) { int as = 0; lock.lock(); try { map.get(a); } finally { lock.unlock(); } return as; } }
ReadWriteHashMap
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package cn.edu.scau.mk.map; import java.util.HashMap; import java.util.concurrent.locks.ReentrantReadWriteLock; /** * * @author MK */ public class ReadWriteHashMap implements In { HashMap<Integer, Integer> map = new HashMap<>(); ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); //390 @Override public void add(int a) { lock.writeLock().lock(); try { if (map.containsKey(a)) { map.put(a, 1 + map.get(a)); } else { map.put(a, 1); } } finally { lock.writeLock().unlock(); } } @Override public int get(int a) { int as = 0; lock.readLock().lock(); try { as = map.get(a); } finally { lock.readLock().unlock(); } return as; } }
SynchronizedHashMap
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package cn.edu.scau.mk.map; import java.util.HashMap; /** * * @author MK */ public class SynchronizedHashMap implements In { HashMap<Integer, Integer> map = new HashMap<>(); @Override public synchronized void add(int a) { if (map.containsKey(a)) { map.put(a, 1 + map.get(a)); } else { map.put(a, 1); } } @Override public synchronized int get(int a) { int as = map.get(a); return as; } }
In
package cn.edu.scau.mk.map; /** * * @author MK */ public interface In { void add(int a); int get(int a); }
Adder
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package cn.edu.scau.mk.map; import java.util.Random; /** * * @author MK */ public class Adder implements Runnable { In in; Random random = new Random(); public Adder(In in) { this.in=in; } @Override public void run() { for (int i = 0; i < 1000; i++) { //in.add(random.nextInt()); in.add(i); } } }
Getter
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package cn.edu.scau.mk.map; import java.util.Random; /** * * @author MK */ public class Getter implements Runnable { In in; Random random = new Random(); public Getter(In in) { this.in=in; } @Override public void run() { for (int i = 0; i < 1000; i++) { //in.add(random.nextInt()); in.get(i); } } }
TestDemo
package cn.edu.scau.mk.map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** * * @author MK */ public class TestDemo { public static void main(String[] args) { In in = null; in = new ReadWriteHashMap(); operate(in); in = new ConcurrentSynchronizedMap(); operate(in); in = new ConcurrentLockMap(); operate(in); in = new SynchronizedHashMap(); operate(in); in = new LockHashMap(); operate(in); } public static void operate(In in) { int poolSize = 1000000; Adder add = new Adder(in); ThreadPoolExecutor threadPool = (ThreadPoolExecutor) Executors.newCachedThreadPool(); long start = System.currentTimeMillis(); for (int i = 0; i < poolSize; i++) { threadPool.execute(add); } System.out.println(threadPool.getActiveCount()); threadPool.shutdown(); try {//等待直到所有任务完成 threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES); long end = System.currentTimeMillis() - start; System.out.print(in.getClass().getSimpleName()+" add:" + end); } catch (InterruptedException e) { e.printStackTrace(); } Getter get = new Getter(in); threadPool = (ThreadPoolExecutor) Executors.newCachedThreadPool(); start = System.currentTimeMillis(); for (int i = 0; i < poolSize; i++) { threadPool.execute(add); } threadPool.shutdown(); try {//等待直到所有任务完成 threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES); long end = System.currentTimeMillis() - start; System.out.println(" get:" + end); } catch (InterruptedException e) { e.printStackTrace(); } } }
三、输出结果
(1)一万并发
6642
ReadWriteHashMap add:1263 get:983
7
ConcurrentSynchronizedMap add:577 get:546
7373
ConcurrentLockMap add:1515 get:1731
7783
SynchronizedHashMap add:1810 get:1607
6632
LockHashMap add:1092 get:1029
(2)十万并发
58095
ReadWriteHashMap add:149181 get:69606
1443
ConcurrentSynchronizedMap add:5678 get:6631
54623
ConcurrentLockMap add:84595 get:77182
48390
SynchronizedHashMap add:63958 get:64696
49078
LockHashMap add:64606 get:64364
(3)百万并发
681252
ReadWriteHashMap add:215943 get:85792
25145
ConcurrentSynchronizedMap add:80593 get:76485
546230
ConcurrentLockMap add:912461 get:821907
636318
SynchronizedHashMap add:845893 get:850142
500129
LockHashMap add:792271 get:808326