深入理解Java线程安全机制:JVM内存模型与synchronized关键字的作用
[id_[id_750490806]6800[id_229702693]6458]id_1891187160]

首先要清楚线程的工作原理。JVM 拥有一个主内存,而每个线程都有属于自己的工作内存。
一个线程对一个 variable 进行操作时,需要在自己的 working memory 中进行。线程在操作 variable 之前,要先将 variable 从主内存加载到自己的 working memory 中。操作完成后,又要将 working memory 中的 variable 写回主内存。这样可以保证多个线程对同一个 variable 的操作是线程安全的。
memory里面建立一个copy,操作完之后再写入main
memory。当多个线程同时对同一个 variable 进行操作时,就有可能出现无法预知的结果。依据上述解释,很容易构思出相应的 scenario。
用 synchronized 的关键在于建立一个 monitor,这个 monitor 可以是需要修改的 variable,也可以是其他你认为合适的 object,比如 method。接着通过给这个 monitor 加锁来达成线程安全,每一个线程在获取到这个锁之后,就需要将其执行完毕。
将其加载到工作记忆中,接着进行使用与分配操作,最后存储到主内存中。
的过程,才会释放它得到的锁。这样就实现了所谓的线程安全。
编写线程安全的代码不需要过度依赖线程同步。
java相关集合
Vector 和 ArrayList 在使用方面有很多相似之处,它们都能够用来表示一组数量可以变化的对象所构成的集合,同时也都可以对其中的元素进行随机访问。
Vector 的方法都具备同步性,是线程安全的。它的这些方法在多线程环境下能够保证数据的一致性和完整性,不会出现数据错乱等问题。例如,添加元素的方法在添加过程中会对数据进行同步处理,确保只有一个线程能够进行添加操作,避免多个线程同时添加导致数据不一致。同样,其他方法如删除元素等也都有相应的同步机制来保障线程安全。thread-safeArrayList 的方法与某种情况不同,因为线程的同步必然会对性能产生影响,所以 ArrayList 的性能比 Vector 好。
ArrayList和LinkedList区别
Java在处理一列数据项时提供了两个类,分别是 ArrayList 和 LinkedList。ArrayList 的内部实现是以内部数组 Object 为基础的。[]从概念上来说,它更像数组。然而,LinkedList 的内部实现是基于一组连接的记录,所以它更像一个链表结构。正因如此,它们在性能上有很大的差别。
从上面的分析能够得知,在 ArrayList 中进行操作时,如果是在其前面或中间插入数据,就必须把其后的所有数据相应地后移,如此一来必然会耗费较多时间。因此,当你的操作是在一列数据的后面添加数据,而非在前面或中间,并且需要随机访问其中的元素时,使用 ArrayList 能够提供较好的性能。
访问链表中的某个元素时,需要从链表的一端开始,沿着连接方向逐个元素地查找,直至找到所需元素。因此,当你的操作是在一列数据的前面或中间添加或删除数据,且要按照顺序访问其中的元素时,就应当使用 LinkedList 。
在编程时,如果 1 和 2 这两种情形交替出现,那么你可以考虑运用 List 这样的通用接口,无需关心其具体的实现情况。在具体的情形当中,它的性能是由具体的实现来予以保证的。
HashTable它采用与 HashMap 相同的存储机制,二者在实现上基本是一致的,然而不同之处在于:
1)、HashMap是非线程安全的,HashTable是线程安全的,内部的方法基本都是synchronized。
2)、HashTable不允许有null值的存在。
在HashTable当在 Java 中调用 put 方法时,如果 key 为 null,就会直接抛出 NullPointerException。此外还有一些细微的差别,例如初始化 Entry 数组的大小等情况,不过其基本思想和 HashMap 是相同的。
HashSet:
1、HashSet基于HashMap实现,无容量限制。
2、HashSet是非线程安全的。
3、HashSet不保证有序。
HashMap:
1HashMap 用数组来存储由 key 和 value 构成的 Entry 对象,不存在容量限制。
2HashMap 是通过 Key 的 hash 值来查找 Entry 对象在数组中的位置的。它对于 hash 冲突会采用链表的方式来进行处理。
3HashMap 在插入元素时可能需要扩大数组的容量。在扩大容量时,需要重新计算 hash,并且要将对象复制到新的数组中。
4、HashMap是非线程安全的。
5、HashMap遍历使用的是Iterator
HashTable
1、HashTable是线程安全的。
2、HashTable中无论是Key,还是Value都不允许为null。
3、HashTable遍历使用的是Enumeration。
TreeSet:
1、TreeSet基于TreeMap实现,支持排序。
2、TreeSet是非线程安全的。
从描述方面来看,TreeSet 与 HashSet 相似,它也是完全依据 Map 来实现的,同时都不具备支持的特性。get通过(int)来获取指定位置的元素,这需要进行遍历获取。同时,TreeSet 还提供了一些在排序方面的支持,比如可以传入 Comparator 实现,还提供了 descendingSet 以及 descendingIterator 等。
TreeMap:
1TreeMap 是一种典型的以红黑树为基础的 Map 实现方式,所以它具备一定的要求,那就是必须要有。Key比较的方法,要么传入Comparator实现,要么key对象实现Comparable接口。
2、TreeMap是非线程安全的。
« 上一篇
Java注解处理器生成代码格式化技巧
下一篇 »
医院病房管理系统ER图设计及关系模式解析