`
woxiaoe
  • 浏览: 284480 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

Java线程学习笔记(七)java中递增不是原子性

    博客分类:
  • Java
阅读更多

以下为测试代码,通过一个自增函数得到最新的值,玩Set你存,看是否有重复。如果递增式原子性的者这个函数不会出错

package com.woxiaoe.study.thread;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 验证Java中递增操作不是递增的
 * @author 小e
 *
 * 2010-4-24 下午09:53:50
 */
public class SerialNumberChecker {
	private static Set<Integer> serialNumberSet = new HashSet<Integer>();
	static int base = 0;
	static int THREAD_SIZE = 10;
	
	static class SerialChecker implements Runnable{
		private SerialNumberChecker snc;
		public SerialChecker(SerialNumberChecker snc) {
			this.snc = snc;
		}
		@Override
		public void run() {
			while(true){
				//int number = snc.nextNumber();
				int number = snc.base ++;
				if(serialNumberSet.contains(number)){
					System.out.println("存在重复值:" + number);
					System.exit(0);
				}else{
					serialNumberSet.add(number);
				}
			}
		}
		
	}
	
	public static void main(String[] args) {
		ExecutorService exec = Executors.newCachedThreadPool();
		SerialNumberChecker snc = new SerialNumberChecker();
		for(int i = 0; i < THREAD_SIZE; i++){
			exec.execute(new SerialChecker(snc));
		}
	}
	
	
	
	
	

}
 

Output:

存在重复值:26202
存在重复值:48602
存在重复值:21441
存在重复值:45719
存在重复值:44544
存在重复值:56256
存在重复值:58230
存在重复值:60097
存在重复值:66177

分享到:
评论
12 楼 wangzaixiang 2010-04-26  
haole 写道
icanfly 写道
haole 写道
Java自增是原子操作,但是通过函数返回就不是原子操作了。
++ base是原子操作,但是return ++ base;就不是了。

别逗了。


建议你看看java编程思想,再发表评论


这位兄弟应该是看过Java编程思想了,我没看过。可能有两种情况:
1、Java编程思想上这么说。斯如是,这个作者在这个问题上错了。这种问题都错,这种书也就没有任何价值。
2、书上没这么说。是haole自己错了。

不懂,千万别装高深,很快就露底了。
11 楼 haole 2010-04-26  
icanfly 写道
haole 写道
Java自增是原子操作,但是通过函数返回就不是原子操作了。
++ base是原子操作,但是return ++ base;就不是了。

别逗了。


建议你看看java编程思想,再发表评论
10 楼 skzr.org 2010-04-26  
++操作的编译码揭示了++确实不是原子操作 装载和存储不是一起的
iload_1 
iinc    1, 1 
istore_1 
9 楼 woxiaoe 2010-04-25  
whaosoft 写道
zhxing 写道
java 的自增自减都不是原子的。。如果要用原子的可以用原子类来做。Java api 上面可找到

嗯 谢谢 嘿嘿我也刚看过了 lz也看看吧

java编程思想里面有讲
8 楼 whaosoft 2010-04-25  
zhxing 写道
java 的自增自减都不是原子的。。如果要用原子的可以用原子类来做。Java api 上面可找到

嗯 谢谢 嘿嘿我也刚看过了 lz也看看吧
7 楼 icanfly 2010-04-25  
haole 写道
Java自增是原子操作,但是通过函数返回就不是原子操作了。
++ base是原子操作,但是return ++ base;就不是了。

别逗了。
6 楼 haole 2010-04-25  
Java自增是原子操作,但是通过函数返回就不是原子操作了。
++ base是原子操作,但是return ++ base;就不是了。
5 楼 woxiaoe 2010-04-25  
NetBus 写道
建议lz仔细去阅读一下编译原理。或者使用 atominteger

呵呵,我的本意是展示这个现象。当然atominteger是一个解决方案。
4 楼 NetBus 2010-04-25  
建议lz仔细去阅读一下编译原理。或者使用 atominteger
3 楼 zhxing 2010-04-25  
java 的自增自减都不是原子的。。如果要用原子的可以用原子类来做。Java api 上面可找到
2 楼 woxiaoe 2010-04-25  
<div class="quote_title">wumingshi 写道</div>
<div class="quote_div">这不能证明递增不是原子性的,只能证明你那个函数不是线程安全的。即使++是原子性的,这个例子也还可能出现你描述的情况。问题是当++完成后,在函数返回前,如果另外一个线程也进入了,然后++了那个变量,然后第一个线程又激活,返回了这个被修改的值,则2个线程返回的值就会相同。 <br>
</div>
<p> </p>
<p> 嗯那样是不严谨,但是java中递增的确不是原子性,我们可以把代码改一下,不调用方法</p>
<pre name="code" class="java">package com.woxiaoe.study.thread;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
* 验证Java中递增操作不是递增的
* @author 小e
*
* 2010-4-24 下午09:53:50
*/
public class SerialNumberChecker {
private static Set&lt;Integer&gt; serialNumberSet = new HashSet&lt;Integer&gt;();
public static int base = 0;
public static int THREAD_SIZE = 10;
public static int nextNumber(){
return ++ base;
}
static class SerialChecker implements Runnable{
private SerialNumberChecker snc;
public SerialChecker(SerialNumberChecker snc) {
this.snc = snc;
}
@Override
public void run() {
while(true){
//int number = snc.nextNumber();
int number = snc.base ++;
if(serialNumberSet.contains(number)){
System.out.println("存在重复值:" + number);
System.exit(0);
}else{
serialNumberSet.add(number);
}
}
}

}

public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
SerialNumberChecker snc = new SerialNumberChecker();
for(int i = 0; i &lt; THREAD_SIZE; i++){
exec.execute(new SerialChecker(snc));
}
}






}
</pre>
<p> Output:</p>
<p>存在重复值:4843<br>存在重复值:15506<br>存在重复值:16677<br>存在重复值:17694<br>存在重复值:18878<br>存在重复值:21118<br>存在重复值:22462<br>存在重复值:23377<br>存在重复值:24101</p>
<p>// 还是有重复值的</p>
1 楼 wumingshi 2010-04-25  
这不能证明递增不是原子性的,只能证明你那个函数不是线程安全的。即使++是原子性的,这个例子也还可能出现你描述的情况。问题是当++完成后,在函数返回前,如果另外一个线程也进入了,然后++了那个变量,然后第一个线程又激活,返回了这个被修改的值,则2个线程返回的值就会相同。

相关推荐

    JAVA 多线程学习笔记

    这篇学习笔记将深入探讨Java多线程的核心概念、实现方式以及相关工具的使用。 一、多线程基础 1. 线程与进程:在操作系统中,进程是资源分配的基本单位,而线程是程序执行的基本单位。每个进程至少有一个主线程,...

    java线程学习笔记

    Java线程学习笔记涉及了Java多线程编程的多个关键知识点,本篇知识点整理将详细解释每个概念及其在Java中的实现方式。 基本知识部分包含了Java线程编程的基础内容,它们是并发编程的基石。 任务Runnable是一个接口...

    Java基础 学习笔记 Markdownr版

    本学习笔记主要涵盖了Java的基础知识,包括面向对象、集合、IO流、多线程、反射与动态代理以及Java 8的新特性等方面,旨在帮助初学者或有经验的开发者巩固和提升Java编程技能。 1. 面向对象(OOP):Java的核心是...

    java学习笔记2(多线程)

    java学习笔记2(多线程)java学习笔记2(多线程)

    java多线程笔记

    Java线程是多任务编程的重要组成部分,它允许程序同时执行多个独立的代码片段,从而提高程序的效率和响应性。本文将深入探讨Java线程的概念、原理以及如何在实际编程中进行有效管理。 首先,我们要了解操作系统中的...

    java多线程中的原子操作

    在Java多线程编程中,原子操作是一种非常关键的概念,它涉及到并发控制和线程安全。原子操作是指在不被其他线程中断的情况下,能够完整执行的一个或一系列操作。这样的操作在多线程环境中可以保证数据的一致性和完整...

    Java多线程笔记

    Java多线程笔记是 Java 编程语言中关于多线程编程的笔记,涵盖了线程基础知识、线程优先级、线程状态、守护线程、构造线程、线程中断等多方面的内容。 获取简单 main 程序中的线程 在 Java 中,可以使用 ...

    java学习笔记markdown

    【Java学习笔记Markdown版】是针对Java初学者和进阶者的一份详尽教程,以Markdown格式编写,便于阅读和整理。Markdown是一种轻量级的标记语言,它允许用户使用易读易写的纯文本格式编写文档,然后转换成结构化的HTML...

    Java 学习笔记Java学习笔记

    Java是一种广泛使用的面向对象的编程语言,由Sun Microsystems(现为Oracle公司的一部分)于1995年发布。...Java学习笔记涵盖了这些核心知识点,通过深入学习和实践,你可以逐步掌握Java编程,并应用于实际项目开发中。

    Java入门学习笔记

    "Java入门第二季学习笔记"可能深入到更复杂的主题,如异常处理、集合框架、IO流和线程。异常处理是Java中处理错误的重要机制,使得程序更加健壮。集合框架包括ArrayList、LinkedList、HashSet、HashMap等数据结构,...

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

    电子书相关:包含4个有关JAVA线程的电子书(几乎涵盖全部有关线程的书籍) OReilly.Java.Threads.3rd.Edition....第七章 Java线程调度例子 第八章 和同步相关的高级主题 第九章 多处理器机器上的并行化 第十章 线程组

    (完整版)最全的java学习笔记(必看).pdf

    Java学习笔记 Java是一种流行的编程语言,广泛应用于Android应用程序开发、Web应用程序开发、桌面应用程序开发等领域。以下是Java学习笔记的摘要信息: 一、Java技术基础 * 1.1 编程语言:Java是一种面向对象的...

    java 线程总结笔记

    花费了一上午的时候 写了一些demo。认识到四种线程池的区别。上传到csdn 供以后学习

    Java学习笔记——良葛格

    "Java学习笔记——良葛格"是一份专为初学者设计的教程资料,由良葛格精心编写,旨在帮助读者掌握JDK5.0版本的Java基础知识。JDK(Java Development Kit)是Java开发的核心工具集,包含了编译器、调试器和运行环境等...

    java多线程学习笔记

    Java多线程是Java编程中的重要概念,它允许程序同时执行多个任务,提高了程序的效率和响应速度。这篇文档和源代码将深入探讨Java多线程的各个方面,旨在帮助学习者掌握这一关键技术。 首先,我们要了解Java中创建...

    Java多线程学习Java多线程学习Java多线程学习Java多线程学习.txt

    Java多线程学习Java多线程学习Java多线程学习Java多线程学习Java多线程学习Java多线程学习Java多线程学习Java多线程学习Java多线程学习Java多线程学习Java多线程学习Java多线程学习Java多线程学习Java多线程学习Java...

    JAVA学习笔记 林信良

    《JAVA学习笔记》是林信良先生的一部深入浅出的Java编程教程,旨在帮助初学者和有一定经验的开发者巩固和提升Java编程技能。这本书涵盖了Java语言的基础到高级概念,是一份宝贵的自学资料。 首先,从基础部分开始,...

Global site tag (gtag.js) - Google Analytics