- 浏览: 773031 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (208)
- Java (77)
- JavaScript (16)
- UML (1)
- Spring (24)
- Hibernate (11)
- J2EE部署 (18)
- 操作系统 (13)
- struts (11)
- jsp (3)
- J2EE (34)
- 数据库 (22)
- tomcat (4)
- apache (2)
- MyEclipse (13)
- Linux (14)
- Ext (6)
- Weblogic (2)
- 数据库 Oracle 空表导出 (1)
- Oracle (3)
- 编码 乱码 (1)
- 多线程 (5)
- jQuery (2)
- Apache Mina (1)
- ibatis (6)
- abator (1)
- svn (1)
- jvm (1)
- ERwin (2)
- mysql (2)
- ant (1)
- memcache (1)
- dubbo (1)
- PowerDesigner (1)
最新评论
-
di1984HIT:
Shallow heap & Retained heap -
tinguo002:
非常感谢 , 太棒了。
Spring注解方式,异常 'sessionFactory' or 'hibernateTemplate' is required的解决方法 -
白天看黑夜:
Apache Mina Server 2.0 中文参考手册(带 ...
Apache Mina – 简单的客户端/服务端应用示例 -
wumingxingzhe:
好文
Shallow heap & Retained heap -
di1984HIT:
学习了!!
工作流(Workflow)和BPM的不同
如果需要使 Map 线程安全,大致有这么四种方法:
1、使用 synchronized 关键字,代码如下
2、使用 JDK1.5提供的锁(java.util.concurrent.locks.Lock)。代码如下
3、使用 JDK1.5 提供的读写锁(java.util.concurrent.locks.ReadWriteLock)。代码如下
这样两个读操作可以同时进行,理论上效率会比方法 2 高。
4、使用 JDK1.5 提供的 java.util.concurrent.ConcurrentHashMap 类。该类将 Map 的存储空间分为若干块,每块拥有自己的锁,大大减少了多个线程争夺同一个锁的情况。代码如下
value = map.get(key); //同步机制内置在 get 方法中
比较:
1、不同步确实最快,与预期一致。
2、四种同步方式中,ConcurrentHashMap 是最快的,接近不同步的情况。
3、synchronized 关键字非常慢,比使用锁慢了两个数量级。如果需自己实现同步,则使用 JDK1.5 提供的锁机制,避免使用 synchronized 关键字。
以下两种写法的区别:
这样因该是线程安全的,只要保证put和get都同步到这个anObject上来
这种写法可能会有问题,因为get和put的key可能是不同的对象
1、使用 synchronized 关键字,代码如下
synchronized(anObject) { value = map.get(key); }
2、使用 JDK1.5提供的锁(java.util.concurrent.locks.Lock)。代码如下
lock.lock(); value = map.get(key); lock.unlock();
3、使用 JDK1.5 提供的读写锁(java.util.concurrent.locks.ReadWriteLock)。代码如下
rwlock.readLock().lock(); value = map.get(key); 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 关键字。
public class MapTest{ public static final int THREAD_COUNT = 1; public static final int MAP_SIZE = 1000; public static final int EXECUTION_MILLES = 1000; public static final int[] KEYS = new int[100]; public static void main(String[] args) throws Exception{ //初始化 Random rand = new Random(); for (int i = 0; i < KEYS.length; ++i) KEYS[i] = rand.nextInt(); //创建线程 long start = System.currentTimeMillis(); Thread[] threads = new Thread[THREAD_COUNT]; for (int i = 0; i < THREAD_COUNT; ++i) { threads[i] = new SynchronizedThread(); //threads[i] = new LockThread(); threads[i].start(); } //等待其它线程执行若干时间 Thread.sleep(EXECUTION_MILLES); //统计 get 操作的次数 long sum = 0; for (int i = 0; i < THREAD_COUNT; ++i){ sum += threads[i].getClass().getDeclaredField("count").getLong(threads[i]); } long millisCost = System.currentTimeMillis() - start; System.out.println(sum + "(" + (millisCost) + "ms)"); System.exit(0); } public static void fillMap(Map<Integer, Integer> map){ Random rand = new Random(); for (int i = 0; i < MAP_SIZE; ++i){ map.put(rand.nextInt(), rand.nextInt()); } } } class SynchronizedThread extends Thread{ private static Map<Integer, Integer> map = new HashMap<Integer, Integer>(); public long count = 0; static { MapTest.fillMap(map); } public void run() { for (;;) { int index = (int)(count % MapTest.KEYS.length); synchronized(SynchronizedThread.class){ map.get(MapTest.KEYS[index]); } ++count; } } } class LockThread extends Thread{ private static Map<Integer, Integer> map = new HashMap<Integer, Integer>(); private static Lock lock = new ReentrantLock(); public long count = 0; static { MapTest.fillMap(map); } public void run() { for (;;) { int index = (int)(count % MapTest.KEYS.length); lock.lock(); map.get(MapTest.KEYS[index]); lock.unlock(); ++count; } } }
以下两种写法的区别:
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可能是不同的对象
发表评论
-
Eclipse,javaw 通过Proxifile代理ipv6协议问题解决
2015-03-17 18:06 2798myeclipse2010升级到myeclipse2014之后 ... -
初始化EHcache CacheManager时报java.net.UnknownHostException
2014-11-13 11:45 12510工程启动时,报一下异常: [wdfportal] [201 ... -
tomcat7可能带来的问题
2013-06-27 00:31 9841、struts标签校验更加严格,如果struts标签中存在嵌 ... -
iBatis执行insert后返回主键
2013-01-18 23:55 1652iBatis插入数据后,返回主键。级联操作很有用。省去了一次的 ... -
Shallow heap & Retained heap
2012-05-16 17:09 49331所有包含Heap Profling功能的工具(MAT, You ... -
Abator —— IBatis 代码生成工具
2012-04-03 18:31 19361、在eclipse安装abator插件http://ibat ... -
使用Eclipse远程调试Tomcat
2012-03-23 22:56 1512有些时候,调试不得不用外网,比如说做支付宝的支付接口,服务器后 ... -
Java compiler level does not match the version of the installed Java project fac
2012-03-02 11:32 1322问题现象:项目图标报错“Java compiler level ... -
WebService的事务处理
2012-03-01 15:03 1562如果你只是要解决两个系统之间的事务同步问题,可以采用判断服务是 ... -
线程池(java.util.concurrent.ThreadPoolExecutor)的使用
2012-02-29 15:50 2509一、简介 线程池类为 j ... -
myeclipse 颜色设置(保护视力)
2012-02-28 09:29 20911.window -> Preferences -> ... -
Quartz表达式解析
2012-02-08 14:40 809字段 允许值 允许的特 ... -
使用iBatis中报 java.sql.SQLException: 无效的列类型异常
2011-12-15 14:46 2244<!--Content表 插入应的 ... -
非常有用的proxool属性详细解说
2011-12-13 16:19 1612Proxool连接池是sourceforge下的一个开源项目, ... -
在工程中查找自己修改的所有代码
2011-12-09 17:41 1049在工程中查找自己修改的所有代码的方法: 1.工程右键 -&g ... -
如何在Eclipse中安装和使用ibatis插件Abator
2011-12-01 21:26 49761、获得abator: http://ibatis. ... -
newCachedThreadPool线程池
2011-11-20 11:35 43037public static ExecutorService n ... -
Apache Mina – 简单的客户端/服务端应用示例
2011-11-19 23:49 5530转自http://javasight.net/2011/05/ ... -
Class.forName()、Class.forName().newInstance() 、New 三者区别!
2011-11-15 09:18 1263终于明白为什么加载数据库驱动只用Class.forName() ... -
Apache MINA 快速入门指南
2011-11-13 12:04 1662最近用到Socket套接字编程,在服务器监听方面还没有具体思路 ...
相关推荐
为了解决HashMap的线程不安全问题,我们可以采取以下几种策略: 1. 使用Collections.synchronizedMap():Java提供了一个便捷的方法,通过Collections.synchronizedMap()可以将HashMap转换为线程安全的Map。但是需要...
### JAVA单例模式的几种实现方法 #### 一、饿汉式单例类 饿汉式单例类是在类初始化时就已经完成了实例化的操作。这种实现方式简单且线程安全,因为实例化过程是在编译期间完成的,不会受到多线程的影响。 **代码...
1. **使用线程安全的类**:Java提供了一些线程安全的Map实现,如`java.util.concurrent.ConcurrentHashMap`。ConcurrentHashMap使用分段锁技术,使得在保证线程安全的同时,提供了较好的并发性能。 2. **同步访问**...
有几种方法可以解决此问题。 例如,英特尔的TBB包含多个“线程安全”容器。 不幸的是,您会发现它们对保留迭代器也不起作用-它们仅确保原子操作。 另一种选择是跳过使用迭代器,仅存储密钥。 但这意味着每次您要...
使用Java Map实现缓存,我们需要考虑以下几个关键点: 1. **缓存初始化**:创建Map实例,可以是HashMap、ConcurrentHashMap或其他适合并发访问的实现,根据实际需求选择。 2. **缓存加载**:当请求的数据不在缓存...
(线程安全)此类遵守与 Hashtable 相同的功能规范,并且包括对应于 Hashtable 的每个方法的方法版本。不过,尽管所有操作都是线程安全的,但检索操作不 必锁定,并且不 支持以某种防止所有访问的方式锁定整个表。...
解决办法是使用`Collections.synchronizedMap()`来同步HashMap,或者使用`ConcurrentHashMap`,这是一种专门为多线程环境设计的线程安全的Map实现。 ```java @Service("userService") Class UserService{ public ...
而Hashtable是古老的线程安全实现,但在多线程环境中通常建议使用ConcurrentHashMap,后者提供了更好的并发性能。 在选择Map实现时,应考虑以下几个因素: 1. 是否需要线程安全性:如果在多线程环境中使用,可以...
根据给定文件的信息,我们可以详细地探讨一下Java中几种主要的集合容器——List、Set以及Map的区别,并且深入了解它们各自的特性和应用场景。 ### 一、List #### 1. ArrayList - **特点**:`ArrayList`是基于动态...
EnumMap 不是线程安全的,如果需要在多线程环境中使用,应通过 Collections.synchronizedMap 方法进行同步。 3. **HashMap**: 它是基于哈希表实现的 Map,提供了所有可选的映射操作,允许 null 键和值。HashMap 并...
本知识点主要关注于Map接口的介绍和几种Map实现类的详解。 首先,Map是一个键值对集合,其中每个键映射到一个值,一个Map不能包含重复的键,每个键最多只能映射到一个值。Map接口中提供了许多方法,例如put方法用于...
除了使用QThread直接编写多线程代码,QT还提供了`QtConcurrent`模块,它提供了一些高级的并发工具,如`run()`、`map()`和`filter()`等,可以方便地在后台线程执行函数,而无需直接管理线程。 此外,QT还支持线程池...
除了使用`ON_MESSAGE`和`SendMessage`之外,还有其他几种常用的方法可以实现跨线程的消息发送: 1. **使用`FindWindow`和`SendMessage`**:这种方法适用于知道目标窗口的类名或标题的情况。 ```cpp HWND hWnd = :...
1. **Collections.synchronizedMap()**:可以使用`Collections.synchronizedMap()`静态方法将`HashMap`包装成线程安全的`SynchronizedMap`。但请注意,尽管这个方法可以确保并发修改的安全,但仍然无法避免迭代时的...
9. **线程安全的数据结构**:标准库中的一些容器,如`std::vector`、`std::map`等,在多线程环境下使用时需要注意其线程安全问题。可以使用线程安全版本的容器,如`std::atomic_flag`和`std::atomic`。 在进行多...
- `HashSet`提供了一种非排序的、非线程安全的实现。 - `TreeSet`提供了一种基于红黑树的实现,可以自然排序或根据自定义比较器排序。 - `LinkedHashSet`保持了元素的插入顺序。 #### Map `Map`接口表示键值对...
此外,还有wait()、notify()和notifyAll()方法用于线程间通信。 3. **线程池**:ExecutorService和ThreadPoolExecutor是Java提供的线程池工具,可以有效管理线程,避免频繁创建和销毁线程带来的开销。 4. **并发...
在实际开发中,选择合适的Map实现类取决于具体需求,如是否需要有序、是否考虑线程安全、性能要求等。例如,如果你需要一个保持插入顺序且高效的Map,那么LinkedHashMap将是不错的选择;如果在多线程环境下,...
在多线程环境下,我们需要确保单例实例的创建只发生一次,以上几种方式除了懒汉式(线程不安全)外,都能保证线程安全。对于反序列化测试,由于默认反序列化会生成新实例,需要重写 `readResolve()` 方法来防止这种...
* 实现数据共享:map 可以实现数据共享,多个线程或进程可以共享同一个 map 对象。 三、如何将 json 转换为 map 在 Java 中,可以使用多种方法将 json 转换为 map。下面是一个使用 JSONObject 和 ListOrderedMap ...