== 和 equals 都是用于比较基本类型和对象。
== | equal | |
---|---|---|
基本类型 | 值是否相等 | 不存在 |
对象 | 两个对象的内存引用,若引用完全相同,返回true | 默认equals方法与==是一样的,一般重写equals方法 |
equals( )方法是Object( )类中,用于检查两个对象的相等性。
如:String中的equals 是判断两个字符串是否相等。而HashMap,HashSet等比较是否为同一个,会对HashCode进行比较。Hasecode返回一个离散的int型整数。在集合类操作中使用,为了提高查询速度。
Serializable: Java 序列化接口。需要添加readObject()和writeObject()方法,可以使用transient关键字进行修饰不必序列化的属性。 在硬盘上读写 读写过程中有大量临时变量的生成,内部执行大量的i/o操作,效率低。
Parcelable :Android 序列化接口 ,效率高,需要实现相应方法 ,对象不能保存到磁盘中。
HashMap:默认的存储大小就是一个容量为16的数组,即使里面没有任何元素,也要开辟内存空间。不断向HashMap里put数据时,当达到一定的容量限制时,HashMap的空间将会扩大,而且扩大后新的空间一定是原来的2倍。如:初始容量为16,初始负载因子loadFactor为0.75 ,当hashmap中元素个数超过16 * 0.75=12的时候,就把数组的大小扩展为2 * 16=32,如果HashMap数据量很大时是比较费内存的。
注:jdk1.8中若链表的结点数大于8,则会转化成红黑树(目的提高查询效率)
ArrayMap:是一个<key,value>映射的数据结构,内部是使用两个数组进行数据存储,一个数组记录key的hash值,另外一个数组记录Value值,它和SparseArray一样,也会对key使用二分法进行从小到大排序,在添加、删除、查找数据的时候都是先使用二分查找法得到相应的index,然后通过index来进行添加、查找、删除等操作。
Thread启动线程都是使用start方法,然后JVM将此线程放到就绪队列中,如果有处理机可用,则执行run方法。
Runnable接口可以避免java单继承特性带来的局限,增强程序健壮性,代码能够被多个线程共享。
Callable接口要实现call方法,并且线程执行完毕后会有返回值,其他的两种方法都是重写run方法,没有返回值。Callable接口提供了一个call()方法可以作为线程执行体,但call()方法比run()方法功能更为强大:call()方法可以有返回值;call()方法可以声明抛出异常。
1,volatile仅作用于变量;synchronized则可以使用在变量、方法、和类。
2,volatile是一种稍弱的同步机制,不会造成线程的阻塞;在访问volatile变量时不会执行加锁操作。synchronized可能会造成线程的阻塞。因此volatile变量是一种比synchronized关键字更轻量级的同步机制。
3,volatile仅能实现变量的修改可见性,是在每次访问变量时都会进行刷新,因此每次访问都是在主内存中得到最新的版本,但不能保证原子性;而synchronized则可以保证变量的修改可见性和原子性,但是效率相对要比volatile低。
volatile关键字,使一个变量在多个线程间可见,也就是一个线程处理另一个线程属性的时候能保证结果是最新的。当一个线程改了被volatile修饰的属性后,另一个线程再改那个属性,会执行缓存过期,通知其他线程重新读取那个属性值
假如一个属性int a = 0,当两个线程都读取那个属性的副本后,两个线程都得到的是0,然后将副本加1,写回去,这个时候两个线程都将a写为1,而不是2.因为线程是将属性副本拿到cpu进行+1然后直接复制给源属性的,所以造成数据出错,即不保证数据原子性。
Java虚拟机:
1、java虚拟机基于栈。 基于栈的机器必须使用指令来载入和操作栈上数据,所需指令更多更多。
2、java虚拟机运行的是java字节码。(java类会被编译成一个或多个字节码.class文件)
Dalvik虚拟机:
1、dalvik虚拟机是基于寄存器。
2、Dalvik运行的是自定义的.dex字节码格式。(java类被编译成.class文件后,会通过一个dx工具将所有的.class文件转换成一个.dex文件,然后dalvik虚拟机会从其中读取指令和数据
3、常量池已被修改为只使用32位的索引,以 简化解释器。
4、一个应用,一个虚拟机实例,一个进程(所有android应用的线程都是对应一个linux线程,都运行在自己的沙盒中,不同的应用在不同的进程中运行。每个android dalvik应用程序都被赋予了一个独立的linux PID(app_*))
1,sleep是来自Thread,wait是来自Object中方法;
2,sleep方法没有释放锁,而wait方法释放了锁。
3,wait,notify,notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用。
4,sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常
5,sleep是Thread类的静态方法。sleep的作用是让线程休眠制定的时间,在时间到达时恢复,调用此方法会让当前线程暂停执行指定的时间,将执行机会(cpu)让给其他线程,但是对象的锁依然保持,因此休眠时间结束后会自动恢复。wait是Object的方法,也就是说可以对任意一个对象调用wait方法,调用wait方法将会将调用者的线程挂起,直到其他线程调用同一个对象的notify方法才会重新激活调用者。