- 浏览: 397744 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (760)
- 股票日志 (26)
- Selenium (0)
- selenium 2 环境的搭建 (1)
- 并发 (7)
- 框架开发 (1)
- 动态代理 (2)
- Struts2 (2)
- POI (2)
- jdk (3)
- maven (31)
- spring (35)
- mysql (31)
- 工作机会 (3)
- xtream (1)
- oracle dbms_metadata GET_DDL (0)
- SSI (1)
- DB (61)
- powermock (4)
- java 基础 (25)
- 多线程 (11)
- 高手 (2)
- java 底层 (2)
- 专业网站 (1)
- 开发联想 (1)
- 开发联想 (1)
- bat文件 (2)
- 清queue 语句 (1)
- 清queue 语句 (1)
- jquery (7)
- html5 (1)
- Jenkins (10)
- Linux (17)
- 工作issue (2)
- tomcat log (3)
- jvm (23)
- 项目细节 (0)
- oracle (41)
- 泛型 (3)
- 新知识点 (1)
- 数据库ddl 语句 (0)
- AQ (2)
- jms (0)
- 网络资源 (6)
- github (6)
- Easymock (1)
- Dom 解析XML (1)
- windows命令 (2)
- java (7)
- 正则表达式 (5)
- sequence (1)
- oracle 表meta信息 (1)
- 小工具技巧 (1)
- 辅助工具 (1)
- Junit (1)
- 泛型 generic (2)
- Java程序设计 (1)
- cglib (2)
- 架构师之路 (1)
- 数据库连接池 (5)
- c3p0 (1)
- eclipse使用 (1)
- oracle sql plus (1)
- 码农人生 (3)
- SVN (15)
- sqlplus (2)
- jsoup (1)
- 网络爬虫 (2)
- 新技能 (1)
- zookeeper (4)
- hadoop (1)
- SVNKIT (1)
- 从工具到知识点的整理 (1)
- log4j (13)
- 读文件 (0)
- 转义字符 (1)
- command (1)
- web service (3)
- 锁 (1)
- shell 脚本 (1)
- 遇到的错误 (2)
- tomcat (14)
- 房产 (5)
- bootstrap jquery ui (1)
- easyui (2)
- 个人征信 (1)
- 读写分离 (1)
- 备份 (1)
- rmi (6)
- webservice (1)
- JMX (4)
- 内存管理 (3)
- java设计 (1)
- timer (1)
- lock (2)
- concurrent (2)
- collection (1)
- tns (1)
- java基础 (15)
- File (1)
- 本机资源 (1)
- bat (1)
- windows (4)
- 数据结构 (3)
- 代码安全 (1)
- 作用域 (1)
- 图 (2)
- jvm内存结构 (1)
- 计算机思想 (1)
- quartz (6)
- Mongo DB (2)
- Nosql (4)
- sql (5)
- 第三方Java 工具 jar 项目 (2)
- drools (1)
- java swing (2)
- 调用console (1)
- runtime (1)
- process (1)
- swing (2)
- grouplayout (1)
- dubbo (0)
- bootstrap (0)
- nodejs (2)
- SVN hooks (1)
- jdbc (3)
- jdbc error (1)
- precedure (1)
- partition_key (1)
- active mq (1)
- blob (2)
- Eclipse (6)
- web server (1)
- bootstrapt (2)
- struts (1)
- ajax (1)
- js call back (1)
- 思想境界拓展 (1)
- JIRA (1)
- log (1)
- jaxb (3)
- xml java互相转换 (1)
- 装修 (2)
- 互联网 (2)
- threadlocal (3)
- mybatis (22)
- xstream (1)
- 排序 (1)
- 股票资源 (1)
- RPC (2)
- NIO (3)
- http client (6)
- 他人博客 (1)
- 代理服务器 (1)
- 网络 (2)
- web (1)
- 股票 (5)
- deadlock (1)
- JConsole (2)
- activemq (3)
- oralce (1)
- 游标 (1)
- 12月13日道富内部培训 (0)
- grant (1)
- 速查 (2)
- classloader (4)
- netty (4)
- 设计模式 (2)
- 缓存 (2)
- ehcache (2)
- framework (1)
- 内存分析 (2)
- dump (1)
- memory (2)
- 多高线程,并发 (1)
- hbase (2)
- 分布式系统 (1)
- socket (3)
- socket (1)
- 面试问题 (1)
- jetty (2)
- http (2)
- 源码 (1)
- 日志 (2)
- jni (1)
- 编码约定 (1)
- memorycache (1)
- redis (13)
- 杂谈 (1)
- drool (1)
- blockingqueue (1)
- ScheduledExecutorService (1)
- 网页爬虫 (1)
- httpclient (4)
- httpparser (1)
- map (1)
- 单例 (1)
- synchronized (2)
- thread (1)
- job (1)
- hashcode (1)
- copyonwriteArrayList (2)
- 录制声音 (1)
- java 标准 (2)
- SSL/TLS (1)
- itext (1)
- pdf (1)
- 钻石 (2)
- sonar (1)
- unicode (1)
- 编码 (4)
- html (1)
- SecurityManager (1)
- 坑 (1)
- Restful (2)
- svn hook (1)
- concurrentHashMap (1)
- 垃圾回收 (1)
- vbs (8)
- visual svn (2)
- power shell (1)
- wmi (3)
- mof (2)
- c# (1)
- concurrency (1)
- 劳动法 (1)
- 三国志游戏 (2)
- 三国 (1)
- 洪榕 (2)
- 金融投资知识 (1)
- motan (1)
- tkmybatis mapper (1)
- 工商注册信息查询 (1)
- consul (1)
- 支付业务知识 (2)
- 数据库备份 (1)
- 字段设计 (1)
- 字段 (1)
- dba (1)
- 插件 (2)
- PropEdit插件 (1)
- web工程 (1)
- 银行业知识 (2)
- 国内托管银行 (1)
- 数据库 (1)
- 事务 (2)
- git (18)
- component-scan (1)
- 私人 (0)
- db2 (14)
- alias (1)
- 住房 (1)
- 户口 (1)
- fastjson (1)
- test (6)
- RSA (2)
- 密钥 (1)
- putty (1)
- sftp (1)
- 加密 (1)
- 公钥私钥 (3)
- markdown (1)
- sweet (1)
- sourcetree (1)
- 好工具 (1)
- cmd (1)
- scp (1)
- notepad++ (1)
- ssh免密登录 (1)
- https (1)
- ssl (2)
- js (2)
- h2 (1)
- 内存 (2)
- 浏览器 (1)
- js特效 (1)
- io (1)
- 乱码 (1)
- 小工具 (1)
- 每周技术任务 (1)
- mongodb (7)
- 内存泄漏 (1)
- 码云 (2)
- 如何搭建java 视频服务器 tomcat (1)
- 资源 (1)
- 书 (1)
- 四色建模法 (1)
- 建模 (1)
- 配置 (1)
- 职位 (1)
- nginx (1)
- excel (1)
- log4j2 (2)
- 做菜 (1)
- jmap (1)
- jspwiki (1)
- activiti (1)
- 工作流引擎 (1)
- 安卓 (1)
- acitviti 例子 (1)
- 二维码 (1)
- 工作流 (1)
- powerdesign (2)
- 软件设计 (1)
- 乐观锁 (1)
- 王者荣耀 (1)
- session (2)
- token (5)
- cookie (4)
- springboot (24)
- jwt (2)
- 项目路径 (1)
- magicbook (1)
- requestType (1)
- json (2)
- swagger (1)
- eolinker (1)
- springdata (1)
- springmvc (1)
- controlleradvice (1)
- profile (1)
- 银行四要素 (1)
- 支付人员资源 (1)
- 支付渠道 (1)
- yaml (1)
- 中文编码 (1)
- mongo (2)
- serializable (1)
- 序列化 (1)
- zyd (1)
- unittest (1)
- 工具 (1)
- Something (1)
- 通达信 (1)
- protobuf (1)
- 算法 (1)
- springcloud (2)
- hikari (1)
- rocketmq (7)
- cachecloud (1)
- serfj (1)
- axure (1)
- lombok (1)
- 分布式锁 (1)
- 线程 (2)
- 同步代码块 (1)
- cobar (1)
- mq (1)
- rabbitmq (1)
- 定时执行 (1)
- 支付系统 (3)
- 唱歌 (1)
- elasticjob (1)
- 定时任务 (1)
- 界面 (1)
- flink (2)
- 大数据 (1)
- 接私活 (0)
- 内部培训 (2)
最新评论
-
dannyhz:
做股票从短线 试水,然后 慢慢发现 波段和 中期的故事可挖, ...
搭台唱戏 -
dannyhz:
http://developer.51cto.com/art/ ...
如何自己开发框架 它的注意点是什么
引用
1 :关注要点,为什么在有synchroniezed方法的同时会出现 Collections.synchronizedList
2 :知识背景: 您可能需要了解java Synchronized方法的加锁的各种机制,包括如何上锁,锁对象
3 : plus: 您需要不断的深化 Java加锁的各种机制
Java代码
1.@NotThreadSafe
2.class BadListHelper <E> {
3. public List<E> list = Collections.synchronizedList(new ArrayList<E>());
4.
5. public synchronized boolean putIfAbsent(E x) {
6. boolean absent = !list.contains(x);
7. if (absent)
8. list.add(x);
9. return absent;
10. }
11.}
这个示例希望实现的功能是为List提供一个原子操作:若没有则添加。因为ArrayList本身不是线程安全的,所以通过集合Collections.synchronizedList将其转换为一个线程安全的类,然后通过一个辅助的方法来为List实现这么个功能。初看起来这个方法没问题,因为也添加了synchronized关键字实现加锁了。
但是仔细分析,你会发现问题。首先对于synchronized关键字,需要说明的是,它是基于当前的对象来加锁的,上面的方法也可以这样写:
Java代码 收藏代码
1.public boolean putIfAbsent(E x) {
2. synchronized(this) {
3. boolean absent = !list.contains(x);
4. if (absent)
5. list.add(x);
6. return absent;
7. }
8.}
所以这里的锁其实是BadListHelper对象, 而可以肯定的是Collections.synchronizedList返回的线程安全的List内部使用的锁绝对不是BadListHelper的对象,应为你在声明和初始化这个集合的过程之中,你尚且都不知道这个对象的存在。所以BadListHelper中的putIfAbsent方法和线程安全的List使用的不是同一个锁,因此上面的这个加了synchronized关键字的方法依然不能实现线程安全性。
下面给出书中的另一种正确的实现:
Java代码 收藏代码
1.@ThreadSafe
2.class GoodListHelper <E> {
3. public List<E> list = Collections.synchronizedList(new ArrayList<E>());
4.
5. public boolean putIfAbsent(E x) {
6. synchronized (list) {
7. boolean absent = !list.contains(x);
8. if (absent)
9. list.add(x);
10. return absent;
11. }
12. }
13.}
如果你要分析这个实现是否正确,你需要搞清楚Collections.synchronizedList返回的线程安全的List内部使用的锁是哪个对象,所以你得看看Collections.synchronizedList这个方法的源码了。该方法源码如下:
Java代码 收藏代码
1.public static <T> List<T> synchronizedList(List<T> list) {
2. return (list instanceof RandomAccess ?
3. new SynchronizedRandomAccessList<T>(list) :
4. new SynchronizedList<T>(list));
5. }
通过源码,我们还需要知道ArrayList是否实现了RandomAccess接口:
Java代码 收藏代码
1.public class ArrayList<E> extends AbstractList<E>
2. implements List<E>, RandomAccess, Cloneable, java.io.Serializable
查看ArrayList的源码,可以看到它实现了RandomAccess,所以上面的synchronizedList放回的应该是SynchronizedRandomAccessList的实例。接下来看看SynchronizedRandomAccessList这个类的实现:
Java代码 收藏代码
1.static class SynchronizedRandomAccessList<E>
2. extends SynchronizedList<E>
3. implements RandomAccess {
4.
5. SynchronizedRandomAccessList(List<E> list) {
6. super(list);
7. }
8.
9. SynchronizedRandomAccessList(List<E> list, Object mutex) {
10. super(list, mutex);
11. }
12.
13. public List<E> subList(int fromIndex, int toIndex) {
14. synchronized(mutex) {
15. return new SynchronizedRandomAccessList<E>(
16. list.subList(fromIndex, toIndex), mutex);
17. }
18. }
19.
20. static final long serialVersionUID = 1530674583602358482L;
21.
22. /**
23. * Allows instances to be deserialized in pre-1.4 JREs (which do
24. * not have SynchronizedRandomAccessList). SynchronizedList has
25. * a readResolve method that inverts this transformation upon
26. * deserialization.
27. */
28. private Object writeReplace() {
29. return new SynchronizedList<E>(list);
30. }
31. }
因为SynchronizedRandomAccessList这个类继承自SynchronizedList,而大部分方法都在SynchronizedList中实现了,所以源码中只包含了很少的方法,但是通过subList方法,我们可以看到这里使用的锁对象为mutex对象,而mutex是在SynchronizedCollection类中定义的,所以再看看SynchronizedCollection这个类中关于mutex的定义部分源码:
Java代码 收藏代码
1.static class SynchronizedCollection<E> implements Collection<E>, Serializable {
2. // use serialVersionUID from JDK 1.2.2 for interoperability
3. private static final long serialVersionUID = 3053995032091335093L;
4.
5. final Collection<E> c; // Backing Collection
6. final Object mutex; // Object on which to synchronize
7.
8. SynchronizedCollection(Collection<E> c) {
9. if (c==null)
10. throw new NullPointerException();
11. this.c = c;
12. mutex = this;
13. }
14. SynchronizedCollection(Collection<E> c, Object mutex) {
15. this.c = c;
16. this.mutex = mutex;
17. }
18.}
可以看到mutex就是当前的SynchronizedCollection对象,而SynchronizedRandomAccessList继承自SynchronizedList,SynchronizedList又继承自SynchronizedCollection,所以SynchronizedRandomAccessList中的mutex也就是SynchronizedRandomAccessList的this对象。所以在GoodListHelper中使用的锁list对象,和SynchronizedRandomAccessList内部的锁是一致的,所以它可以实现线程安全性。
发表评论
-
copyOnWriteArrayList的解释和范例
2017-06-06 01:12 391http://blog.csdn.net/u011116672 ... -
concurrentHashMap实现机制
2017-05-09 10:48 449https://www.ibm.com/developerwo ... -
关于aqs abstractqueuesynchronizer这个 并发的核心类
2017-03-07 18:05 405http://www.infoq.com/cn/article ... -
在数据库连接池 编程里使用了copyonwritearrayList
2017-02-13 15:07 356@Override public void con ... -
java 并发教程
2015-06-18 00:35 348http://www.iteye.com/magazines/ ... -
并发基础
2015-05-07 01:29 332http://www.iteye.com/magazines/ ...
相关推荐
标题中的"Collections.synchronizedList"是指Java集合框架中的一个静态工厂方法,用于将任何List转换为线程安全的List。这个方法是Java中实现多线程环境下的集合操作的重要工具,确保在并发访问时数据的一致性和完整...
- 使用`Collections.synchronizedList()`方法包装集合。 - 使用并发集合类(如`ConcurrentHashMap`, `CopyOnWriteArrayList`)。 #### 八、高级主题 - **泛型与类型安全**:使用泛型确保类型安全,避免运行时的`...
2. 使用`Collections.synchronizedList(new ArrayList)`: 这种方法通过装饰器模式,将传入的`ArrayList`包装成`synchronizedList`,对所有调用的方法添加了同步控制。这样在并发环境下,多个线程调用`add()`等方法时...
- `Collections.synchronizedList(List l)`: 创建同步列表。 - `Collections.synchronizedMap(Map m)`: 创建同步映射。 - `Collections.synchronizedSet(Set s)`: 创建同步集合。 - `Collections....
在实际开发中,如果对线程安全有需求,可以考虑使用Collections.synchronizedList()方法将ArrayList转换为线程安全的列表,或者使用CopyOnWriteArrayList,这是一个更适合并发读写场景的线程安全实现。而如果在单...
例如,`Collections.synchronizedList`和`Collections.synchronizedMap`。同步集合在每个方法上加锁,确保同一时间只有一个线程可以执行操作。虽然提供了基本的线程安全性,但它们不是高度优化的并发解决方案,因为...
- `SynchronizedList` 是 `java.util.Collections` 类的一个静态内部类。它不直接实现 `List` 接口,而是通过包装一个现有的 `List` 实例(例如 `ArrayList` 或 `LinkedList`),并为这个实例添加同步机制来提供...
2. 使用`Collections.synchronizedList`:这个静态方法可以将给定的`ArrayList`转换为线程安全的列表。在内部,它通过在方法调用上添加`synchronized`关键字来实现同步。这提供了线程安全的访问,但仍然需要谨慎处理...
此外,ArrayList不是线程安全的,如果在多线程环境中使用,需要通过Collections.synchronizedList方法使ArrayList同步。 二、ArrayList源码分析 1. 底层实现:ArrayList的内部字段`elementData`是一个transient的...
2. 使用`Collections.synchronizedList()`:Java标准库提供了同步包装器,将普通集合转换为线程安全的集合,如`List`可以通过`Collections.synchronizedList()`进行转换。 3. 使用`ReentrantLock`:如果需要更细...
通过 `Collections.synchronizedList()`,我们确保了在并发访问时列表操作的正确性。 3. **排序**:`Collections.sort(list);` 使用 `Collections` 类的静态方法 `sort()` 对线程安全的列表进行排序。这个方法会...
除了以上五点,还有一些实用的工具类,如`Collections.synchronizedList()`用于同步列表,`Collections.unmodifiableList()`创建只读列表,以及`Collections.reverse()`用于反转列表等。了解并善用这些特性,可以...
这样,尽管ArrayList本身不是线程安全的,但通过Collections工具类的静态方法,我们可以创建一个线程安全的ArrayList的包装器,使得并发访问时能够避免数据竞争问题。 除了ArrayList,List接口还有其他实现,比如...
如果没有这样的对象存在,列表应该使用Collections.synchronizedList方法“包装”。 这最好在创建时完成,以防止意外的不同步访问列表: List list = Collections.synchronizedList(new ArrayList(...)); The ...
如果该对象不存在,该列表应被“包装”使用Collections.synchronizedList方法。 这最好在创建时完成,以防止意外的名单不同步访问: List list = Collections.synchronizedList(new ArrayList(...)); 此类的返回的...
为了在多线程环境下使用,可以使用Collections.synchronizedList、Collections.synchronizedMap等静态工厂方法来创建线程安全的容器。 - **ConcurrentXX类**:Java并发包(java.util.concurrent)提供了线程安全的...
- **ArrayList**和**LinkedList**:同样是非线程安全的,需要通过`Collections.synchronizedList()`进行同步。 - **CopyOnWriteArrayList**:适用于读多写少的场景,写操作时会创建新列表并复制原列表中的元素,...