`
woxiaoe
  • 浏览: 276247 次
  • 性别: 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线程学习笔记

    java多线程笔记

    二、Java中的线程 3 三、Java中关于线程的名词解释 3 四、线程的状态转换和生命周期 4 Java线程:创建与启动 7 Java线程:线程名称的设定及获取 10 Java线程:线程栈模型与线程的变量 12 Java线程:线程的调度-休眠 ...

    java学习笔记2(多线程)

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

    多线程学习笔记

    多线程学习笔记,通过平时的学习所做的一些笔记,希望对广大同仁有所帮助

    JAVA 多线程学习笔记

    NULL 博文链接:https://baobeituping.iteye.com/blog/1190260

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

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

    java线程 线程学习资料 java线程教程

    java线程 线程 教程 java线程教程 java线程学习资料 本教程有什么内容? 本教程研究了线程的基础知识— 线程是什么、线程为什么有用以及怎么开始编写使用线程的简单 程序。 我们还将研究更复杂的、使用线程的应用...

    java 线程总结笔记

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

    Java线程讲解Java线程讲解

    Java线程讲解Java线程讲解Java线程讲解Java线程讲解Java线程讲解Java线程讲解Java线程讲解Java线程讲解Java线程讲解Java线程讲解

    Java多线程笔记

    多线程学习笔记,好资源。包括线程基础等知识多线程学习笔记,好资源。包括线程基础等知识

    基于java的开发源码-java多线程反射泛型及正则表达式学习笔记和源码.zip

    基于java的开发源码-java多线程反射泛型及正则表达式学习笔记和源码.zip 基于java的开发源码-java多线程反射泛型及正则表达式学习笔记和源码.zip 基于java的开发源码-java多线程反射泛型及正则表达式学习笔记和源码....

    Java并发编程学习笔记 pdf 多线程编程

    Java并发编程学习笔记,...目前,在JAVA并发编程方面的论述系统且内容详实的技术资料不太多,Java并发编程学习笔记是作者在实际工作中的经验总结,一般来说,当你读完了前8章,你已经足以可以应对JAVA的多线程编程了。

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

    java学习笔记5(java多线程)java学习笔记5(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多线程学习笔记

    这篇文档和对应的源代码 博文链接:https://interper56-sohu-com.iteye.com/blog/172303

    Java线程Java线程Java线程Java线程

    Java线程Java线程Java线程Java线程Java线程Java线程

Global site tag (gtag.js) - Google Analytics