map线程实现同步的几种方法
2010-08-24 20:54
357 查看
如果需要使 Map 线程安全,大致有这么四种方法:
1、使用 synchronized 关键字,代码如下
Java代码
2、使用 JDK1.5提供的锁(java.util.concurrent.locks.Lock)。代码如下
Java代码
3、使用 JDK1.5 提供的读写锁(java.util.concurrent.locks.ReadWriteLock)。代码如下
Java代码
这样两个读操作可以同时进行,理论上效率会比方法 2 高。
4、使用 JDK1.5 提供的 java.util.concurrent.ConcurrentHashMap 类。该类将 Map 的存储空间分为若干块,每块拥有自己的锁,大大减少了多个线程争夺同一个锁的情况。代码如下
value = map.get(key); //同步机制内置在 get 方法中
比较:
1、不同步确实最快,与预期一致。
2、四种同步方式中,ConcurrentHashMap 是最快的,接近不同步的情况。
3、synchronized 关键字非常慢,比使用锁慢了两个数量级。如果需自己实现同步,则使用 JDK1.5 提供的锁机制,避免使用 synchronized 关键字。
Java代码
以下两种写法的区别:
synchronized
(anObject)
{
value = map.get(key);
}
synchronized
(anObject)
{
map.put(key, value);
}
这样因该是线程安全的,只要保证put和get都同步到这个anObject上来
synchronized
(key)
{
value = map.get(key);
}
synchronized
(key)
{
map.put(key, value);
}
这种写法可能会有问题,因为get和put的key可能是不同的对象
1、使用 synchronized 关键字,代码如下
Java代码
1. synchronized(anObject) { 2. value = map.get(key); 3. }
2、使用 JDK1.5提供的锁(java.util.concurrent.locks.Lock)。代码如下
Java代码
1. lock.lock(); 2. value = map.get(key); 3. lock.unlock();
3、使用 JDK1.5 提供的读写锁(java.util.concurrent.locks.ReadWriteLock)。代码如下
Java代码
1. rwlock.readLock().lock(); 2. value = map.get(key); 3. rwlock.readLock().unlock();
这样两个读操作可以同时进行,理论上效率会比方法 2 高。
4、使用 JDK1.5 提供的 java.util.concurrent.ConcurrentHashMap 类。该类将 Map 的存储空间分为若干块,每块拥有自己的锁,大大减少了多个线程争夺同一个锁的情况。代码如下
value = map.get(key); //同步机制内置在 get 方法中
比较:
1、不同步确实最快,与预期一致。
2、四种同步方式中,ConcurrentHashMap 是最快的,接近不同步的情况。
3、synchronized 关键字非常慢,比使用锁慢了两个数量级。如果需自己实现同步,则使用 JDK1.5 提供的锁机制,避免使用 synchronized 关键字。
Java代码
1. public class MapTest{ 2. public static final int THREAD_COUNT = 1; 3. public static final int MAP_SIZE = 1000; 4. public static final int EXECUTION_MILLES = 1000; 5. public static final int[] KEYS = new int[100]; 6. public static void main(String[] args) throws Exception{ 7. 8. //初始化 9. Random rand = new Random(); 10. for (int i = 0; i < KEYS.length; ++i) KEYS[i] = rand.nextInt(); 11. //创建线程 12. long start = System.currentTimeMillis(); 13. Thread[] threads = new Thread[THREAD_COUNT]; 14. for (int i = 0; i < THREAD_COUNT; ++i) { 15. threads[i] = new SynchronizedThread(); 16. //threads[i] = new LockThread(); 17. threads[i].start(); 18. } 19. 20. //等待其它线程执行若干时间 21. Thread.sleep(EXECUTION_MILLES); 22. //统计 get 操作的次数 23. long sum = 0; 24. for (int i = 0; i < THREAD_COUNT; ++i){ 25. sum += threads[i].getClass().getDeclaredField("count").getLong(threads[i]); } 26. long millisCost = System.currentTimeMillis() - start; 27. System.out.println(sum + "(" + (millisCost) + "ms)"); 28. System.exit(0); 29. } 30. 31. public static void fillMap(Map<Integer, Integer> map){ 32. Random rand = new Random(); 33. for (int i = 0; i < MAP_SIZE; ++i){ 34. map.put(rand.nextInt(), rand.nextInt()); 35. } 36. } 37. } 38. class SynchronizedThread extends Thread{ 39. private static Map<Integer, Integer> map = new HashMap<Integer, Integer>(); 40. public long count = 0; 41. static { 42. MapTest.fillMap(map); 43. } 44. public void run() { 45. for (;;) { 46. int index = (int)(count % MapTest.KEYS.length); 47. synchronized(SynchronizedThread.class){ 48. map.get(MapTest.KEYS[index]); 49. } 50. ++count; 51. } 52. } 53. } 54. 55. 56. 57. class LockThread extends Thread{ 58. private static Map<Integer, Integer> map = new HashMap<Integer, Integer>(); 59. private static Lock lock = new ReentrantLock(); 60. public long count = 0; 61. static { 62. MapTest.fillMap(map); 63. } 64. public void run() { 65. for (;;) { 66. int index = (int)(count % MapTest.KEYS.length); 67. lock.lock(); 68. map.get(MapTest.KEYS[index]); 69. lock.unlock(); 70. ++count; 71. } 72. } 73. }
以下两种写法的区别:
synchronized
(anObject)
{
value = map.get(key);
}
synchronized
(anObject)
{
map.put(key, value);
}
synchronized(anObject) { value = map.get(key); } synchronized(anObject) { map.put(key, value); }
这样因该是线程安全的,只要保证put和get都同步到这个anObject上来
synchronized
(key)
{
value = map.get(key);
}
synchronized
(key)
{
map.put(key, value);
}
synchronized(key) { value = map.get(key); } synchronized(key) { map.put(key, value); }
这种写法可能会有问题,因为get和put的key可能是不同的对象
相关文章推荐
- 【Java面试题】23 java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用?
- java多线程有几种实现方法?线程之间如何同步
- java中有几种方法可以实现一个线程?用什么关键字修饰同步
- 【Java面试题】26 多线程有几种实现方法?同步有几种实现方法? 当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?
- Java中有几种方法实现一个线程,用什么关键字修饰同步方法?stop()和suspend()方法为何不提倡使用?
- java 中有几种方法可以实现一个线程? 用什么关键字修 饰同步方法? stop()和 suspend()方法为何不推荐使用?
- java基础问题---java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用
- java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用
- java开发线程篇1:java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用?
- java中有几种方法可以实现一个线程?用什么关键字修饰同步方法 stop()和suspend()方法为何不推荐使用?
- java多线程有几种实现方法?线程之间如何同步
- java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用?
- java有几种方法可以实现一个线程?用什么关键字修饰同步方法?
- java实现同步map的几种方法(lock,synchronized,rwlock,ConcurrentHashMap,hashtable,SynchronizedMap)
- JAVA遍历map的几种实现方法代码
- Java线程同步实现方法
- 线程安全的单例模式的几种实现方法分享
- 多线程有几种实现方法?同步有几种实现方法?
- Form程序中,在线程里,回调方法,实现同步。
- java中有几种方法可以实现一个线程