`
Paper_Gou
  • 浏览: 2432 次
  • 性别: 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线程理解小程序"的初衷,帮助开发者学习如何在Android环境中正确地管理和使用线程。 首先,我们需要理解Java中的线程创建方式。最基础的是通过实现`Runnable`接口或继承`Thread`类来创建线程。实现`...

    Java线程详解大全

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

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

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

    java线程分析工具TDA

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

    java 线程 dump 分析工具 2.3.3

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

    Java多线程知识点总结

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

    java线程深入解析

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

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

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

    Java线程使用教程

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

Global site tag (gtag.js) - Google Analytics