-
2022-01-17 17:05:28
import sun.misc.Unsafe; import java.lang.reflect.Field; public class Main { private static final Unsafe unsafe; static { try { unsafe = getUnsafe(); } catch (NoSuchFieldException | IllegalAccessException e) { throw new IllegalStateException("Unsafe获取失败!", e); } } private static Unsafe getUnsafe() throws NoSuchFieldException, IllegalAccessException { Field field = Unsafe.class.getDeclaredField("theUnsafe"); field.setAccessible(true); return (Unsafe) field.get(null); } @SafeVarargs public static <T> String objectAddress(T... objects) { long offset = unsafe.arrayBaseOffset(objects.getClass()); long factor = 8; final long i1 = (unsafe.getInt(objects, offset) & 0xFFFFFFFFL) * factor; return "0x" + Long.toHexString(i1); } public static void main(String[] args) { Object o = new Object(); System.out.println(o.hashCode()); System.out.println(o.hashCode()); System.out.println(objectAddress(o)); System.out.println(objectAddress(o)); byte[] ignored = new byte[10240]; System.gc(); System.out.println(objectAddress(o)); System.out.println(o.hashCode()); }
更多相关内容 -
js 对象操作问题:把一个对象A赋值给另一个对象B (1)对象B 修改 不会影响 A对象(2)对象B修改影响 A对象
2020-05-29 10:12:21js 对象操作 对象原型操作 把一个对象A赋值给另一个对象B 并且对象B 修改 不会影响 A对象 我最近在做一个vue + element-UI + vue-resource + vuex项目的时候,遇到了一个对象的问题。 当我们在项目需要 复制一个对象...js 对象操作 对象原型操作 把一个对象A赋值给另一个对象B 并且对象B 修改 不会影响 A对象
我最近在做一个vue + element-UI + vue-resource + vuex项目的时候,遇到了一个对象的问题。当我们在项目需要 复制一个对象到另一个对象并且 被复制的对象不能受复制后的对象的影响。
对象B修改影响 A对象(Object.assign特殊)
我先总结下 我们哪些方法可以复制对象
// 直接赋值 var obj1 = { a: 1 }; var obj2 = obj1; console.log(obj2); // { a: 1 } // 通过 Object.assign() 这个属性来进行复制 var obj = { a: 1 }; var obj2 = Object.assign({}, obj); console.log(obj2); // { a: 1 } // 通过 for in 循环赋值 var obj1={ a: 1, b: { c: 2 }, c: 0 } var obj2={} for( var key in obj1 ){ obj2[key]=obj[key] } console.log(obj2); // { a: 1, b: { c: 2 }, c: 0 }
以上的方法中 都可以把一个对象的键值赋值给另一个对象(但是我们可以测试出来obj2修改他的键值,obj1的键值也会被修改),
这就跟我家的钥匙刚开始是一把钥匙,然后我到配钥匙的地方配了一把一模一样的钥匙,那么我的这把原来的钥匙可以开我家的门,拿我家的东西,那么配的那把钥匙,也可以打开我家的门,拿走我家的东西。
其实我们想做的是,我们心买了一个房子,只是房子里的东西摆设跟我原来的房子是一模一样的,唯独不一样的就是,我原来家的钥匙只能开原来家的门,新家的钥匙只能开新家的门,虽然两个房子里的东西是一模一样的,但是都是没有实际的关联关系。那么这样我门需要怎么做呢。
对象B 修改 不会影响 A对象
我们可以先看看下面的这个方法
// 使用 Object.assign() 方法复制对象 let obj1 = { a: 0 , b: { c: 0}}; let obj2 = Object.assign({}, obj1); console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}} obj1.a = 1; console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 0}} console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}} obj2.a = 2; console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 0}} console.log(JSON.stringify(obj2)); // { a: 2, b: { c: 0}} obj2.b.c = 3; console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 3}} console.log(JSON.stringify(obj2)); // { a: 2, b: { c: 3}}
我们可以看到上面 Object.assign() 的这个方法虽然可以复制我第一层的对象值,并且当我obj2修改第一层的数据时,obj1不会受到影响。
但是我们在修改obj2 里 b 对象里的c的值得时候,这个时候 obj1 里的 b 对象里的 c 的值也发生了改变,这就说明了,Object.assign()这个方法不是深层的复制对象,只是让对象里第一层的数据没有了关联性,但是对象内的对象则跟被复制的对象有着关联性的。那么我们其实可以想象,怎么才能让他们完全没有关联性没呢。
字符串类型 和 对象类型 肯定是没有关联性的 ,因为它们的类型都不一样,肯定是没有可比性和关联性的。 有了这样的想法我觉得我们就有办法决绝这个问题了;
// 这个最简单暴力的处理 两个对象的关联性的问题 obj1 = { a: 0 , b: { c: 0}}; let obj3 = JSON.parse(JSON.stringify(obj1)); obj1.a = 4; obj1.b.c = 4; console.log(JSON.stringify(obj3)); // { a: 0, b: { c: 0}}
上面的代码已经可以体现出来我们刚才的一个假设,我们先把obj1 转成了字符串类型, 这样他就失去了对象的属性和一切的特性,然后我们再把它转成一个对象类型,这样我们心生成的对象是通过字符串转换过来的,已经是一个新的对象,然后再赋值给obj2 ,这样就相当于,我把我原来家的布置等东西,用设计稿的方式展现出来,然后我们又买了一个新家,按着原来的设计方式重构了出来,这样两个房子的内饰是一模一样的,但是门的钥匙不一样,这样就失去了以前的关联性。
以上的方法可以封装成方法方便使用
var function cloneObjectFn (obj){ // 对象复制 return JSON.parse(JSON.stringify(obj)) } var obj1={a:2,b{c:0}} var obj2=cloneObjectFn(obj1) console.log(obj2) // {a:2,b{c:0}}
-
Synchronized 互斥块(对象锁) 一个对象和一个monitor 的关系
2017-06-09 08:10:551、synchronized(obj):可以任意指定对象.2、synchronized(this):当前对象:当一个类加到内存时,常量池有一个地址直接指向当前正在执行的对象. 3、public synchronized void run():当前对象(this),这是实...Synchronized :锁住的是对象,出现synchronized表示随后的代码块要用到共享数据了,要锁住了。
一、3种形式。
1、synchronized(obj):可以任意指定对象.
2、synchronized(this):当前对象:当一个类加到内存时,常量池有一个地址直接指向当前正在执行的对象.
3、public synchronized void run():当前对象(this),这是实例方法,每一方法里存着一个This.方法
对象:可以是普通类 public class Test {}, 也可以是干活线程类 ,只要是new 类名 的所有对象。
**所以synchronized(this){} 和synchronized 方法差不多,反正是锁当前对象。
二、对于锁类其实也一样,因为一个类入内存后,还是java.lang.Class 的类对象。所以还是锁对象。
三、锁的数据:一个类成员数据:对象实例变量,类变量
1、object instance variables:对象实例变量,存在堆中。
2、class variables:类变量,存在method area。
如果您正在写一个变量,这个变量有可能随后被另一个线程读,
或您正在读一个变量,这个变量有可能随后被另一个线程写,
这时你必须用到变量的地方放一个synchronized,
四、例子
1、简单需求
例如:银行个人账户(对象):卡号,余额
如果一个小店主,顾客很多,如果都用微信付款的话,有可能同一时刻访问店主的银行个人账户的问题。
当一个顾客对店主的账号余额进行加减时,锁住账号,退出后,另一个顾客才能继续付钱,
顾客是看不见这些过程,只管提交就行,银行应该是相应的服务软件接收用户的请求。
2、代码说明
1>有4个线程,main()主线程,3个顾客子线程
因为是几个顾客有可能同时付款,所以需要线程。
2>一个店主银行个人账户的对象(对象里面有共享资源,余额)
银行个人账户的对象(peraccount)对应一个monitor。
3>执行步骤(只取其中一个结果分析)
第一:main线程执行到threads[0].start(),threads[1].start(),threads[2].start();
即3个线程入就绪对象,这是main代码执行完,cpu空
第二:调度程序选择threads[0]进入cpu。
第三:
(一)当jvm行到synchronized peraccount 这一句时,表示peraccount 对象里面有共享数据,
去取一把钥匙,看人家是否已经锁住共享数据了.去哪里取呢?monitor大楼。
(二)这时cpu空,调度程序安排thread[2]入cpu,thread[0]去monitor大楼取钥匙去了
两个过程同时执行。
(三)当jvm 执行到threads[2]到synchronized peraccount 时,又该去peraccount monitor大楼取钥匙了。
同时cpu还是空。
(四)调度程序安排thread[1]入cpu执行,在monitor大厅等待,
同时cpu空,这时,thread[0]已经占用特殊房间,表示取得钥匙,获得一把锁,锁住后面的代码。
1》调度程序安排thread[0]进入Cpu,因为后面的代码已经被thread[0]锁住,所以一直占cpu执行完。
cpu空,同时特殊房间空,thread[1]和thread[2]竞争,thread[1]进入特殊房间,获得锁。
2》thread[1]占用特殊房间,表示取得钥匙,获得一把锁,锁住后面的代码。所以一直占cpu执行完,
cpu空,同时特殊房间空,thread[2]进入特殊房间。
3》thread[2]已经占用特殊房间,表示取得钥匙,获得一把锁,锁住后面的代码。所以一直占cpu执行完,cpu空
整个过程完
3、图形
4、代码
package concurrency;
/**
* 银行个人账户,共享数据,
* cardnumber,balance
* 一个卡号,多人可以对余额进行修改。
*
*/
class Account {
private String cardnumber;//卡号
private float balance; //余额
public Account(String cardnumber, float balance) {
this.cardnumber = cardnumber;
this.balance = balance;
}
// 存钱
public void deposit(float sum) {
balance= balance+sum;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//得到当前钱数。
public float getBalance() {
return balance;
}
}
/**
* PayToAccount 现在是静态类
* 可以new 多个对象,表示多人用微信付款
* 每一支付的人和店主的个人账号相连
*/
public class PayToAccount implements Runnable {
private Account peraccount; //表示和店主个人账号对象相连接
private float sum;
public PayToAccount(Account peraccount,float sum) {
this.peraccount = peraccount;
this.sum=sum;
}
public void run() {
System.out.println(Thread.currentThread().getName()+" run()");
synchronized (peraccount) {//到这里表示要锁住店主的个人账号对象了,后面涉及对同一对象进行操作。
System.out.println(Thread.currentThread().getName()+" 取得钥匙");
peraccount.deposit(this.sum);
System.out.println(Thread.currentThread().getName() + ":"
+peraccount.getBalance());
}
}
/**客户微信软件---扫一下,哪么微信软件应该提取了店主的个人账号,点支付之后,应该是执行PayToAccount的run操作。
* 下面是模拟顾客扫微信的功能,只用了固定的3个顾客,但是现实顾客数无法确定。
*/
public static void main(String[] args) {
//店主墙上的微信号(也就是店主的银行个人账号)
Account account = new Account("yang", 50.0f);//
//相当客户扫一扫:把自己和店主的银行个人账号相连,
//账号,存的钱数。
PayToAccount buyer1 = new PayToAccount(account,50.0f);
PayToAccount buyer2 = new PayToAccount(account,125.0f);
PayToAccount buyer3 = new PayToAccount(account,310.0f);
/**
* 相当3个客户都点了支付按钮,付钱,
* 涉及同时对一个账号进行操作,
* 建立三个新的驱动线程带上三个新的干活线程(客户付款线程)
*在这个例子中,三个驱动线程是new Thread,
*干活线程是buyer1,buyer2,buyer3,锁住的对象是Account(共享资源)
*/
Thread threads[] = new Thread[3];
Thread threads[] = new Thread[3];
threads[0] = new Thread(buyer1, "第一个顾客" );
threads[1] = new Thread(buyer2, "第二个顾客" );
threads[2] = new Thread(buyer3, "第三个顾客" );
/**
/**
* 付钱,客户任务已经完成,就是等银行返回消息了。
*/
threads[0].start();
threads[1].start();
threads[2].start();
}
}只是为了理解monitor,所以选择
其中的一个运行结果:
第一个顾客 取得钥匙
第一个顾客:100.0
第二个顾客 取得钥匙
第二个顾客:225
第三个顾客 取得钥匙
第三个顾客:535.0 -
为什么JAVA中一些类用另的一个类的对象来调用?
2018-05-10 13:35:00我不明白的是为什么需要通过先获得con对象才能通过con对象获得stmt后才能获得rt对象.不明白这种对象的调用原理..新手.才接触java没多久,,希望各位大神能帮忙解惑.说细致点..谢谢..最好能举例说明.. ---------------... -
JAVA复制对象给另一个对象
2016-06-25 22:40:15JAVA复制对象给另一个对象 标签: javahibernateobject 2012-03-23 16:46 14881人阅读 评论(0) 收藏 举报 分类: J2SE(113) 版权声明:本文为博主原创文章,未经博主允许...分类:
版权声明:本文为博主原创文章,未经博主允许不得转载。
今天算是遇到一个问题了。相当苦恼。
需求如下:有2个相同id的对象,但它们的值不同。其中一个对象要用到另一个对象的属性值。
由于在hibernate的sessionFactory().getSession中不能存在2个相同id的对象。故此,想出复制对象。
找了很多地方,发现有2种方法可以达到复制对象的目的,只是最后这种方法还是没有解决我的问题。仅此记下来吧。
1,克隆clone
Java支持克隆一个对象的值到另一个对象,简单的克隆和深度克隆,深度克隆可能包括继承,嵌套,没有用到,所以也就没怎么去研究它。
首先,克隆的对象需要实现 Cloneable接口,重写其中的clone()方法,为了使clone()方法在外部可用,需要将重写的方法访问修饰符改成public级别。
dv是deliverymanreport克隆的一个对象。它拥用克隆后的属性和方法。
2,序列化和反序列化Serializable
序列化的对象要实现Serializable接口才能实现序列化。
序列化后,通过反序列化可以得到和当前对象一样的对象。它比克隆来得更准备。但也就不一定最好,如果这个对象在之前被修改,序列化后可能就会出问题了。
序列化经常用于文件传递的读取。尤其是在缓存中用得比较多,通过序列化可以将对象缓存在硬盘中。这在登录系统缓存用户权限和角色等信息最常见。而用对克隆对象,也不失为一种很好的方法。 -
java new对象的理解
2021-02-12 17:14:29在JAVA里就是创建一个新的实例,或者说一个新的对象,一个普通类在没有实例化之前,就是new之前,它的属性,方法等等在内存中都是不存在的。只有使用new了以后,这个类的一些东西在内存中才会真的存在,也就是说只有new了... -
计算机--什么是对象,为什么要面向对象,怎么才能面向对象?
2017-03-02 22:00:57... 这个对象不是C#中的实例,C#中我们把一个类的实例也叫做对象,这种对象严格的说应该是面向对象的编程实现(OOP)中的对象,面向对象编程,也不是面向类的实例编程。对象的定义是人们要进行研 -
java面向对象
2018-08-21 16:51:59本文内容是根据毕晓东老师的视频教程总结而得。... 面向对象和面向过程都是一种思想 面向过程强调的是功能、行为 面向对象:将功能封装进对象,强调具备了功能的对象 面向对象是基于面向过程的 面向过程例子: ... -
JSP的9个内置对象,4个常用对象
2018-12-02 22:51:37JSP的内置对象(9个)是可以直接使用的。 内置对象 真实的对象 方法 request HttpServletRequest setAttribute() 、getAttribute() response HttpServletResponse addCookie()、getWriter() ... -
JVM如何判断一个Java对象是否可以回收
2018-08-31 14:19:43总所周知,Java将程序员从内存...在此之前,我们先来复习一个和Java对象回收有关的知识,那便是finalize方法,这是一个在Object类中定义的方法,如果我们重写了finalize方法,那么在对象被回收之前将会调用finaliz... -
用java类和对象写一个简单的回合制对战游戏
2018-04-21 18:30:50一、什么是对象,什么是类类比现实生活,任何一个具体的事物都可以称为对象,比如某台电脑,某本书,某个人……而类就是根据对象相似的特征和功能进行分类,对象是具体的,类是抽象的。二、类的基本格式public class... -
String str = new String("abc")到底创建几个String对象
2019-03-06 13:09:40紧接着这段代码之后的往往是这个问题,那就是这行代码究竟创建了几个String对象呢?相信大家对这道题并不 陌生,答案也是众所周知的,2个。接下来我们就从这道题展开,一起回顾一下与创建String对象相关的一些 JAVA... -
深入理解Java类型信息(一):Class对象与类型转换
2019-03-20 19:54:19RTTI(Run-Time Type Identification) 运行时类型识别,最先出现在C++里,引入这个机制是为了让程序在运行时能根据基类的指针或引用来获得该指针或引用所指的对象的实际类型。 Java中的RRTI则是源于《Thinking in ... -
el表达式 ,在获取到对象时 ,对象有个属性是students是一个List<Student> 集合
2016-09-19 12:02:46为什么 ${对象.students} 按理说得到的是List<Student> ...... 什么也不能操作啊 假如我想操作第一个 也不能${对象.students[0]} 啊。。我想用c:foreach 搞出每一个student -
JavaScript基础之对象与内置对象(三)
2021-07-30 16:07:54在 JavaScript 中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数值、数组、函数等。 对象是由属性和方法组成的: 属性:事物的特征,在对象中用属性来表示(常用名词) 方法:事物的... -
重新认识java(一) ---- 万物皆对象
2016-11-27 21:39:37如果你现实中没有对象,至少你在java世界里会有茫茫多的对象,听起来是不是很激动呢? -
Java虚拟机中对象探秘--对象头创建、对象头、对象锁、synchoronized底层实现
2018-05-18 16:26:01今天看别人的博客,讲到面试相关的问题,其中有一个知识点是:synchronized关键字,Java对象头、Markword概念、synchronized底层实现,monitorenter和monitorexit指令,一脸蒙逼,虽然早期把《深入理解Java虚拟机》... -
【软件工程习题(含参考答案)】面向对象章节
2020-04-20 01:47:04把程序整体划分成一个个独立命名且可独立访问的完成单个子功能的模块。采用模块化,软件结构清晰,不仅容易设计也容易阅读和理解,有利于软件开发工程的组织管理 2、抽象:抽出事物的本质特性,暂不考虑其细节,... -
Java 中,类、类对象、泛型之间的转换
2021-02-20 22:55:10类、类对象、泛型之间的转换R为非泛型获得类通过类型名来获得类通过对象来获得类通过类名字符串来获得类通过类来获得类名字符串通过类来获得对象使用R的无参数构造器来创建对象使用R的有参数构造器来创建对象T为泛型... -
两个对象HashCode相同即 哈希碰撞解决方案
2018-10-25 12:36:53先了解下Java中堆栈的...我们知道,对象Hash的前提是实现equals()和hashCode()两个方法,那么HashCode()的作用就是保证对象返回唯一hash值,但当两个对象计算值一样时,这就发生了碰撞冲突。如下将介绍如何处理冲突... -
Qt 对象树
2020-04-08 20:14:55作者:billy 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 Object Tree Model 先来看一下 QObject 的构造...即每一个 QObject 对象有且仅有一个父对象,但可以有很多个子对象。按... -
Java引用对象
2018-12-11 10:09:03简介 在写了15年C/C++之后,我于1999年开始写Java。借助指针切换(pointer handoffs)等编码实践或者Purify等工具,我认为自己对C风格的内存管理已经得心应手了,甚至已经不记得...接着我就遇到了第一个OutOfMemor... -
java反射对象和new出来的对象有什么区别
2019-04-26 08:45:44一、****************************...b1:反射属于动态编译,意思就说只有到运行时才会去获得该对象的实例,大多框架都是使用反射获取对象实例,如Spring 二、*****************************************************... -
单例对象无法被回收的原因 - gc回收机制
2021-04-16 12:10:53单例对象无法被回收的真正原因要从java垃圾回收器开始说起JAVA垃圾对象判断准则Java中判断一个对象是否可以被回收是根据“可达性”来判定的。可达性:以一系列的称为 “GC Roots”的对象作为起始点,然后向下搜索,... -
Java提高—对象克隆(复制)/对象属性拷贝
2017-10-18 21:09:59对象克隆(复制)假如说你想复制一个简单变量。很简单:int apples = 5; int pears = apples; 不仅仅是int类型,其它七种原始数据类型(boolean,char,byte,short,float,double.long)同样适用于该类情况。但是如果你... -
Java - 简述一下面向对象的“六原则一法则”。
2019-03-17 15:38:20(单一职责原则想表达的就是”高内聚”,写代码最终极的原则只有六个字”高内聚、低耦合”,所谓的高内聚就是一个代码模块只完成一项功能,在面向对象中,如果只让一个类完成它该做的事,而不涉及与它无关的领域就是... -
C++面向对象基础
2018-05-20 12:40:59优点:确保用户代码不会无意间破坏封装对象的状态被封装的类的具体实现细节可以随时改变,而无须调整用户级别的代码继承性:让某种类型对象获得另一个类型对象的属性和方法。继承可以扩展已存在的代码多态性:同一... -
《C++面向对象程序设计》✍千处细节、万字总结(建议收藏)
2021-06-04 15:42:25文章目录《C++面向对象程序设计》✍千处细节、万字总结一、面向对象程序设计二、C++基础2.1 C++的产生和特点2.2 一个简单的C++示例程序2.3 C++在非面向对象方面对C语言的扩充输入和输出cinconst修饰符void型指针内联... -
WDF驱动简介及几个驱动对象介绍
2019-07-24 09:41:44设备驱动程序是硬件设备连接到计算机系统的软件接口,任何设备都必须有相应的驱动程序才能在计算机系统上正常工作。设备驱动程序的优劣直接关系到整个系统的性能和稳定性,因此,设计和开发稳定高效的驱动程序...