有下面两个类:
package Demo; import java.util.HashMap; public class HashMapTest{ private HashMap<String, Integer> map = new HashMap<String, Integer>(); public synchronized void add(String key){ Integer value = map.get(key); System.out.println("object1 -------- " +value); if(value == null){ map.put(key, 1); }else{ map.put(key, value+1); } } }
package Demo; import java.util.concurrent.ConcurrentHashMap; public class ConcurrentHashMapTest { private ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<String, Integer>(); public void add(String key){ Integer value = map.get(key); System.out.println("object2 -------- " + value); if(value == null){ map.put(key, 1); }else{ map.put(key, value+1); } } }
两个都类中都有一个map容器对象,第一个类中容器为线程不安全的HashMap对象,第二类中为线程安全的ConcurrentHashMap 对象。同样的也都有一个添加计数方法add,第一个类中是加了锁synchronized,第二个中直接访问。
两个类都是希望自己的数据容器map能够在多线程的访问的情况下正常存取。
第一种使用了线程不安全容器加锁的方式实现,第二种直接使用了线程安全容器进行访问。
下面是测试代码:
package Demo; public class ComputeObject implements Runnable{ public static HashMapTest hashMapTest = new HashMapTest(); public static ConcurrentHashMapTest concurrentHashMapTest = new ConcurrentHashMapTest(); public static void main(String[] args) { for (int i = 0; i < 10; i++) { new Thread(new ComputeObject()).start(); } } @Override public void run() { hashMapTest.add("key"); concurrentHashMapTest.add("key"); } }
主线程中开了10条子线程对两个容器进行访问。
理想结果是:两个容器除去第一次为空外,他们的中的属性key值应当为9.
object1 -------- null object2 -------- null object1 -------- 1 object2 -------- 1 object1 -------- 2 object2 -------- 2 object1 -------- 3 object1 -------- 4 object2 -------- 3 object1 -------- 5 object2 -------- 4 object1 -------- 6 object2 -------- 5 object1 -------- 7 object2 -------- 5 object1 -------- 8 object2 -------- 6 object2 -------- 6 object1 -------- 9 object2 -------- 7
可以看到,类一成功实现了多线程下的数据安全访问,然而类二中出现了大量的重复数据输出。
当时我们将类二中的add方法同样加上synchronized方法,输出两个输出都变为9。
这是因为对于ConcurrentHashMap中,它只对put,remove操作使用了同步操作,get操作并不影响,这就可能在每次读入的时候,读入了相同的数据实现了重复的增加。
所以在使用ConcurrentHashMap时,应当保证足够的小心。
jdkAPI:
获取操作(包括 get)通常不会受阻塞,因此,可能与更新操作交迭(包括 put 和 remove)。获取会影响最近完成的 更新操作的结果。对于一些聚合操作,比如 putAll 和 clear,并发获取可能只影响某些条目的插入和移除。类似地,在创建迭代器/枚举时或自此之后,Iterators 和 Enumerations 返回在某一时间点上影响哈希表状态的元素。它们不会 抛出 ConcurrentModificationException
。不过,迭代器被设计成每次仅由一个线程使用。
相关推荐
电子书相关:包含4个有关JAVA线程的电子书(几乎涵盖全部有关线程的书籍) OReilly.Java.Threads.3rd.Edition.Sep.2004.eBook-DDU Java Thread Programming (Sams) java线程第二版中英文 java线程第二版中英文 ...
Java多线程是Java编程中的一个重要概念,它允许程序同时执行多个任务,提高了程序的效率和响应速度。在Java中,实现多线程有两种主要方式:继承Thread类和实现Runnable接口。 1. 继承Thread类: 当我们创建一个新...
Java线程是多任务编程的重要概念,它允许程序同时执行多个独立的任务,从而...在"线程池.rar"和"线程实例"这两个文件中,你可以找到关于这些概念的具体示例代码,通过学习和实践,可以深入理解Java线程的运用和管理。
在Java编程环境中,单线程指的是程序执行过程中只有一个线程在运行。这意味着任何时刻只能执行一个任务,上一个任务完成后才会进行下一个任务。单线程模型简化了程序设计,降低了程序复杂度,使得开发者可以更专注于...
基于java多线程的一款小游戏基于java多线程的一款小游戏基于java多线程的一款小游戏 基于java多线程的一款小游戏基于java多线程的一款小游戏基于java多线程的一款小游戏 基于java多线程的一款小游戏基于java多线程的...
Java线程是Java编程中非常重要的一个概念,它可以帮助开发者实现多任务并行处理,提高程序的执行效率。理解线程的创建、生命周期管理以及线程间的同步和通信机制对于开发高质量的Java应用至关重要。希望以上内容能够...
Java线程是Java编程中的重要概念,特别是在多核处理器和并发处理中不可或缺。Java线程允许程序在同一时间执行多个不同的任务,从而提高了程序的效率和响应性。在燕山大学信息学院计算机系的课程中,李峰教授讲解了...
java 线程工具类 java 线程工具类java 线程工具类 java 线程工具类java 线程工具类 java 线程工具类java 线程工具类 java 线程工具类java 线程工具类 java 线程工具类java 线程工具类 java 线程工具类java 线程工具...
有点乐趣,小java线程监控程序, 小java线程监控程序 小java线程监控程序
JAVA线程dump是指在JAVA程序中,当前线程的状态和调用堆栈的快照,能够帮助开发者了解当前程序的执行情况,诊断问题和性能瓶颈。生成JAVA线程dump的方法在不同的操作系统下是不同的,在Windows环境中,可以敲击Ctrl-...
在Java编程中,多线程是一项关键特性,它允许程序同时执行多个任务,极大地提高了程序的效率...通过这个项目,开发者可以深入理解Java线程的创建、控制以及线程安全问题,同时也能锻炼到GUI编程和实时动画更新的能力。
这就是"java线程理解小程序"的初衷,帮助开发者学习如何在Android环境中正确地管理和使用线程。 首先,我们需要理解Java中的线程创建方式。最基础的是通过实现`Runnable`接口或继承`Thread`类来创建线程。实现`...
线程是程序中一个单一的顺序控制流,它在程序的上下文中运行,但具有独立的执行路径。多线程则是指在单个程序内同时运行多个不同的线程,每个线程执行不同的任务。线程共享同一份程序内存空间,但拥有各自的程序...
Java程序中的多线程技术是实现并发操作的关键,尤其在处理并发读写数据时,如在本例中,我们有两条线程分别负责读取和写入学生的成绩...通过学习这个程序,我们可以深入理解Java线程的使用以及并发编程中的核心概念。
Java线程分析是Java开发中的重要环节,尤其是在处理性能优化、死锁排查或者并发问题时。TDA(Thread Dump Analyzer)是一款强大的Java线程分析工具,它能够帮助开发者深入理解应用在运行时的线程状态,包括线程的...
Java的TDA线程转储分析器是一个用于分析Sun Java VM生成的线程转储和堆信息的小型Swing GUI(目前用1.4测试)。它从提供的日志文件中解析线程转储和类直方图。它提供关于发现的线程转储的统计信息,提供关于锁定监视器...
Java多线程是Java编程语言中一个非常重要的概念,它允许开发者在一个程序中创建多个执行线程并行运行,以提高程序的执行效率和响应速度。在Java中,线程的生命周期包含五个基本状态,分别是新建状态(New)、就绪...
Java线程是Java编程语言中的核心概念,尤其在多任务处理和并发编程中扮演着重要角色。线程允许一个程序内部同时执行多个独立的控制流,使得程序能够更高效地利用处理器资源。本文将深入解析Java线程的相关知识点,...
每个Java程序都有一个主线程,即由JVM启动并执行main方法的线程。线程代表了程序中的执行流,可以在不同的线程之间切换以共享CPU时间。线程的状态包括新建、运行、中断和死亡。线程的生命周期始于新建,通过调用...
Java线程是Java编程语言中的一个核心概念,它允许程序同时执行多个任务,极大地提高了程序的并发性和效率。本教程将深入探讨Java线程的使用,帮助开发者掌握这一关键技术。 一、线程基础 1. **线程的概念**:线程...