package com.jvm.cas; import org.junit.Test; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicStampedReference; /** * Created by ZhouChenmin on 2018/3/24. */ public class AtomicStampedReferenceTest { @Test public void simpleTest(){ Integer initRef = 1; Integer initStem = 1; AtomicStampedReference<Integer> data = new AtomicStampedReference(initRef,initStem); boolean ok = data.compareAndSet(1,2,1,2); System.out.println(ok); ok = data.compareAndSet(2,3,data.getStamp(),data.getStamp() + 1); System.out.println(ok); System.out.println(data.getReference()); } @Test public void concurrentTest() throws InterruptedException { int initRef = 1; int initStem = 1; final AtomicStampedReference<Integer> data = new AtomicStampedReference(initRef,initStem); ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 5, 5, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new ThreadFactory() { @Override public Thread newThread(Runnable r) { Thread thread = new Thread(r); thread.setDaemon(false); return thread; } }); int threadSize = 5; final CountDownLatch countDownLatch = new CountDownLatch(threadSize); for (int i = 1 ;i <= threadSize ; i ++){ threadPoolExecutor.execute(new Runnable() { @Override public void run() { try { for (int j =0 ;j < 100 ; j ++){ incr(data); } }finally { System.out.println(Thread.currentThread().getName() + " has done the job"); countDownLatch.countDown(); } } }); } try { countDownLatch.await(10,TimeUnit.SECONDS); } catch (InterruptedException e) { } System.out.println(countDownLatch.getCount()); if (countDownLatch.getCount() > 0){ System.out.println("依旧有线程在跑" + countDownLatch.getCount()); } System.out.println(data.getReference()); System.out.println(data.getStamp()); /** * 既然还有线程没有跑完,并且也不是守护线程,为什么程序就结束了???????????????? */ } public void incr (final AtomicStampedReference<Integer> data){ int mexRetry = 0; while (true){ int value = data.getReference(); int stamp = data.getStamp(); if ( !data.compareAndSet(value , value+1 , stamp , stamp+1) ) { mexRetry++; }else { return; } if (mexRetry > 20){ //throw new RuntimeException("retry count reach"); try { Thread.sleep(1000); mexRetry= 0; } catch (InterruptedException e) { e.printStackTrace(); } } } } /** * testIncr */ @Test public void testIncr (){ int initRef = 1; int initStem = 1; final AtomicStampedReference<Integer> data = new AtomicStampedReference(initRef,initStem); incr(data); incr(data); System.out.println(data.getReference()); System.out.println(data.getStamp()); } }
期望输出501,结果输出128,请找出程序BUG,提示BUG在incr方法中。
运行junit test concurrentTest()
相关推荐
Java的自动装箱功能极大地简化了基本数据类型与它们对应的包装类之间的相互转换。然而,这一特性可能会引起一些不易察觉的副作用,这些副作用往往是由于JVM对某些包装类对象实现了缓存机制所致。 1. ==和equals行为...
在Java编程语言中,自动装箱(Autoboxing)和自动拆箱(Unboxing)是两个重要的特性,它们简化了基本类型(如int、double等)与对应的包装类(如Integer、Double等)之间的转换过程。这些特性是在Java 5引入的,极大...
1. 自动装箱:当我们将一个基本数据类型赋值给包装类的对象时,Java编译器会自动进行装箱操作。例如,`int a = 10; Integer b = a;` 在这里,a被转换成Integer对象b,这就是自动装箱。 2. 自动拆箱:相反,当我们...
Java语言在设计时引入了自动装箱和拆箱机制,以方便开发者在基本类型与它们对应的包装类之间进行转换。这个特性在提高编程效率的同时,也可能带来一些隐藏的陷阱,尤其是在性能敏感的代码中。本篇文章将深入探讨Java...
此外,对于较大的整数,例如超过-128到127范围的`Integer`对象,使用自动装箱创建的新对象每次都会指向不同的内存地址,因此即使数值相等,对象引用也会不同。这一点在处理大量自动装箱的整数时尤其需要注意,因为它...
这是因为Java的自动装箱拆箱机制,使得Integer和int之间的转换更加便捷,但同时也可能导致意外的结果。 例如,面试题中提到的Integer对象交换问题,乍一看似乎无法通过常规方法实现。通常,我们可能会尝试如下代码...
Integer的缓存机制对于频繁进行自动装箱和拆箱操作的场景尤其重要。例如,当我们处理大量小整数值时,缓存机制能显著减少内存开销和提高性能。然而,超出缓存范围的Integer对象,即使它们的值相同,也会被视为不同的...
Java中的自动装箱和拆箱是自JDK 1.5版本引入的一种语言特性,它极大地简化了基础数据类型(如int)与它们对应的包装类(如Integer)之间的转换过程。这一特性使得开发者无需手动创建包装类实例或使用显式类型转换,...
Java 自动转换是Java编程语言中的一个重要特性,它涉及到类型转换、自动装箱与拆箱、数据类型提升等多个方面。在Java中,自动转换极大地方便了开发人员处理不同类型的数据,提高了代码的可读性和效率。以下是关于...
### Java中的自动装箱与拆箱 #### 一、概念介绍 在Java中,自动装箱(Autoboxing)和拆箱(Unboxing)是Java编译器提供的一种特性,用于在基本数据类型和对应的包装类之间进行自动转换。这种特性简化了编程过程中...
我们也可以使用缓存机制来减少自动装箱和拆箱的次数,从而提高程序的性能。 结论 自动装箱和拆箱是Java语言中一个非常重要的特性,它可以使得程序员的代码更加简洁易懂。但是,这个过程也会引起一些耗时问题。本文...
Java中的自动装箱和拆箱是自J2SE 5.0版本引入的特性,它极大地简化了基本数据类型与其对应的包装类之间的转换过程。基本数据类型包括int、double、boolean等,而包装类如Integer、Double和Boolean分别对应这些基本...
自动装箱是指 Java 编译器在编译时将基本类型 int 转换为 Integer 对象的过程。 使用 "==" 运算符比较 Integer 对象 在 Java 中,"==" 运算符用于比较两个对象的引用是否相同,而不是比较对象的实际值。因此,当...
Java是一种广泛使用的面向对象的编程语言,其设计目标是实现跨...了解这些Java核心知识点对于准备面试和提升编程技能至关重要,无论是初学者还是经验丰富的开发者,都可以通过深入理解这些概念来增强自己的Java能力。
自动装箱是指Java将原始类型值转换成对应的对象的过程,如将int类型的变量转换成Integer对象。反之,将对象转换成原始类型值的过程称为拆箱。因为这里的装箱和拆箱是自动进行的非人为转换,所以就称作为自动装箱和...
3. **Integer缓存机制**:为了提高效率,`Integer` 类在-128到127范围内提供了缓存,对于这个范围内的整数,自动装箱不会每次都创建新的对象。 通过以上分析,我们可以更深入地理解Java中的自动装箱、拆箱及其对...
项目里遇到的小问题的 整理
在Java编程语言中,自动装箱(Autoboxing)和自动拆箱(Unboxing)是从Java 1.5版本开始引入的一项特性,其目的是简化原始类型(Primitive Types)与它们对应的包装类(Wrapper Classes)之间的转换过程。...
自动装箱和拆箱的实现依赖于Java中的特殊机制。每个包装类都包含一个名为`value`的私有成员变量,用于存储基本数据类型的值。例如,在`Integer`类中,有一个名为`value`的`int`类型成员变量。 - **自动装箱实现**:...