`
Paper_Gou
  • 浏览: 2446 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

java线程中的一个小问题

阅读更多

 

 有下面两个类:

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。不过,迭代器被设计成每次仅由一个线程使用。

分享到:
评论

相关推荐

    线程 JAVA java线程 java线程第3版 java线程第2版第3版合集

    电子书相关:包含4个有关JAVA线程的电子书(几乎涵盖全部有关线程的书籍) OReilly.Java.Threads.3rd.Edition.Sep.2004.eBook-DDU Java Thread Programming (Sams) java线程第二版中英文 java线程第二版中英文 ...

    java多线程Demo

    Java多线程是Java编程中的一个重要概念,它允许程序同时执行多个任务,提高了程序的效率和响应速度。在Java中,实现多线程有两种主要方式:继承Thread类和实现Runnable接口。 1. 继承Thread类: 当我们创建一个新...

    java线程实例 各种小Demo

    Java线程是多任务编程的重要概念,它允许程序同时执行多个独立的任务,从而...在"线程池.rar"和"线程实例"这两个文件中,你可以找到关于这些概念的具体示例代码,通过学习和实践,可以深入理解Java线程的运用和管理。

    JAVA单线程多线程

    在Java编程环境中,单线程指的是程序执行过程中只有一个线程在运行。这意味着任何时刻只能执行一个任务,上一个任务完成后才会进行下一个任务。单线程模型简化了程序设计,降低了程序复杂度,使得开发者可以更专注于...

    基于java多线程的一款小游戏.zip

    基于java多线程的一款小游戏基于java多线程的一款小游戏基于java多线程的一款小游戏 基于java多线程的一款小游戏基于java多线程的一款小游戏基于java多线程的一款小游戏 基于java多线程的一款小游戏基于java多线程的...

    java线程.pdf

    Java线程是Java编程中非常重要的一个概念,它可以帮助开发者实现多任务并行处理,提高程序的执行效率。理解线程的创建、生命周期管理以及线程间的同步和通信机制对于开发高质量的Java应用至关重要。希望以上内容能够...

    Java线程.ppt

    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线程dump是指在JAVA程序中,当前线程的状态和调用堆栈的快照,能够帮助开发者了解当前程序的执行情况,诊断问题和性能瓶颈。生成JAVA线程dump的方法在不同的操作系统下是不同的,在Windows环境中,可以敲击Ctrl-...

    java多线程控制小球程序

    在Java编程中,多线程是一项关键特性,它允许程序同时执行多个任务,极大地提高了程序的效率...通过这个项目,开发者可以深入理解Java线程的创建、控制以及线程安全问题,同时也能锻炼到GUI编程和实时动画更新的能力。

    Java线程详解大全

    线程是程序中一个单一的顺序控制流,它在程序的上下文中运行,但具有独立的执行路径。多线程则是指在单个程序内同时运行多个不同的线程,每个线程执行不同的任务。线程共享同一份程序内存空间,但拥有各自的程序...

    java程序 两个线程实现学生成绩的读写

    Java程序中的多线程技术是实现并发操作的关键,尤其在处理并发读写数据时,如在本例中,我们有两条线程分别负责读取和写入学生的成绩...通过学习这个程序,我们可以深入理解Java线程的使用以及并发编程中的核心概念。

    java 线程 dump 分析工具 2.3.3

    Java的TDA线程转储分析器是一个用于分析Sun Java VM生成的线程转储和堆信息的小型Swing GUI(目前用1.4测试)。它从提供的日志文件中解析线程转储和类直方图。它提供关于发现的线程转储的统计信息,提供关于锁定监视器...

    java线程分析工具TDA

    Java线程分析是Java开发中的重要环节,尤其是在处理性能优化、死锁排查或者并发问题时。TDA(Thread Dump Analyzer)是一款强大的Java线程分析工具,它能够帮助开发者深入理解应用在运行时的线程状态,包括线程的...

    Java多线程知识点总结

    Java多线程是Java编程语言中一个非常重要的概念,它允许开发者在一个程序中创建多个执行线程并行运行,以提高程序的执行效率和响应速度。在Java中,线程的生命周期包含五个基本状态,分别是新建状态(New)、就绪...

    java线程深入解析

    Java线程是Java编程语言中的核心概念,尤其在多任务处理和并发编程中扮演着重要角色。线程允许一个程序内部同时执行多个独立的控制流,使得程序能够更高效地利用处理器资源。本文将深入解析Java线程的相关知识点,...

    Java多线程机制(讲述java里面与多线程有关的函数)

    每个Java程序都有一个主线程,即由JVM启动并执行main方法的线程。线程代表了程序中的执行流,可以在不同的线程之间切换以共享CPU时间。线程的状态包括新建、运行、中断和死亡。线程的生命周期始于新建,通过调用...

    Java线程使用教程

    Java线程是Java编程语言中的一个核心概念,它允许程序同时执行多个任务,极大地提高了程序的并发性和效率。本教程将深入探讨Java线程的使用,帮助开发者掌握这一关键技术。 一、线程基础 1. **线程的概念**:线程...

    java多线程经典案例

    而线程通信可能体现在当一个线程完成转账后通知另一个线程继续执行的场景。线程阻塞则可能出现在账户余额不足,需要等待外部充值后再继续转账的情况。 通过分析并实践`threadTest`案例,我们可以深入理解Java多线程...

Global site tag (gtag.js) - Google Analytics