JDK源码
一、Object
1.1 registerNatives()
native是调用本地实现方法,而registerNatives则是对本地方法注册,装载本地库。在Object初始化时执行。
private static native void registerNatives();
static {
registerNatives();
}
1.2 getClass()
getClass()返回的是运行时的对象,而class返回的是编译时的对象。此方法不能被重写。
public final native Class<?> getClass();
1.3 hashCode()
public native int hashCode();
主要时保证像hashmap、set等集合插入数据的时候,直接比较hashCode值,这样如果hashCode值不同,那这两个对象就是不相同的,就不需要进行比较equals()方法,可以直接进行数据的插入,极大的提高了插入效率。如果hashCode值相同,则出现hash碰撞,那么就需要进行比较equals()。
1.4 equals()
在Object中equals和==是等价的。所以在Object中两个对象的引用相同,那么一定就是相同的。在我们自定义对象的时候一定要重写equals方法。 -自反性:对于任何非空引用值 x,x.equals(x) 都应返回 true。
-对称性:对于任何非空引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true。
-传递性:对于任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 应返回 true。
-一致性:对于任何非空引用值 x 和 y,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上 equals 比较中所用的信息没有被修改
-对于任何非空引用值 x,x.equals(null) 都应返回 false
public boolean equals(Object obj) {
return (this == obj);
}
1.5 clone()
创建并返回一个对象的副本, 浅拷贝:被复制的对象的所有成员属性都有与原来的对象相同的值, 而所有的对其他对象的引用仍然指向原来的对象。换言之,浅层复制仅仅复制所考虑的对象,而不复制它所引用的对象; 深拷贝:复制的是对象的值和引用,被拷贝的对象修改属性值,复制的对象属性不变。
protected native Object clone() throws CloneNotSupportedException;
1.6 toString()
返回一个对象的字符串,建议所有子类重写这个方法。 可以看出toString是返回的类名加16进制无符号整数形式返回此哈希码的字符串表示形式。
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
1.7 finalize()
垃圾回收的方法
protected void finalize() throws Throwable { }
1.8 notify()
一个线程调用共享对象的notify()方法后,会唤醒一个该共享变量上调用wait系列方法被挂起的线程。一个共享变量可能会有多个线程等待,唤醒哪个等待的线程是随机的。
public class WaitNotifyTest {
static final Object resourceA = new Object();
public static void main(String[] args) throws InterruptedException {
Thread threadA = new Thread(
new Runnable() {
@Override
public void run() {
try {
System.out.println("start");
synchronized (resourceA) {
resourceA.wait(-1);
}
System.out.println("end");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
);
threadA.start();
Thread.sleep(10000);
System.out.println("threadA interupt start ");
threadA.interrupt();
System.out.println("threadA interupt end ");
}
1.9 notifyAll()
会唤醒所有该共享变量上由于调用wait系列方法被挂起的线程。
public class NotifyAllThreadTest {
private static final Object resourceA = new Object();
public static void main(String[] args) throws InterruptedException {
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println("A start");
synchronized (resourceA) {
resourceA.wait();
}
System.out.println("A end");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread threadB = new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println("B start");
synchronized (resourceA) {
resourceA.wait();
}
System.out.println("B end");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread threadC = new Thread(new Runnable() {
@Override
public void run() {
synchronized (resourceA){
System.out.println("C start notify");
resourceA.notifyAll();
}
}
});
threadA.start();
threadB.start();
// Thread.sleep(1000);
threadC.start();
threadA.join();
threadB.join();
threadC.join();
}
1.10 wait()
当调用wait()方法时,调用该线程被阻塞起来。调用的wait()方法线程必须先获得该对象的监视器锁。
public final void wait() throws InterruptedException {
wait(0);
}
@Slf4j
public class TestWaitThread {
public static final Logger log=LoggerFactory.getLogger(TestWaitThread.class);
private static volatile Object resourceA=new Object();
private static volatile Object resourceB=new Object();
public static void main(String[] args) throws InterruptedException {
// 创建线程A
Thread threadA=new Thread(
new Runnable() {
@Override
public void run() {
synchronized (resourceA){
log.info("ThreadA GET resourceA");
synchronized (resourceB){
log.info("ThreadA GET resourceB");
try {
resourceA.wait();
} catch (InterruptedException e) {
log.error("resourceA release Lock fail");
}
}
}
}
}
);
// 创建线程B
Thread threadB=new Thread(
new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
synchronized (resourceA) {
log.info("ThreadB GET resourceA");
synchronized (resourceB) {
log.info("ThreadB GET resourceB");
try {
resourceA.wait();
} catch (InterruptedException e) {
log.error("resourceB release Lock fail");
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
);
threadA.start();
threadB.start();
threadA.join();
threadB.join();
}@Slf4j
public class TestWaitThread {
public static final Logger log=LoggerFactory.getLogger(TestWaitThread.class);
private static volatile Object resourceA=new Object();
private static volatile Object resourceB=new Object();
public static void main(String[] args) throws InterruptedException {
// 创建线程A
Thread threadA=new Thread(
new Runnable() {
@Override
public void run() {
synchronized (resourceA){
log.info("ThreadA GET resourceA");
synchronized (resourceB){
log.info("ThreadA GET resourceB");
try {
resourceA.wait();
} catch (InterruptedException e) {
log.error("resourceA release Lock fail");
}
}
}
}
}
);
// 创建线程B
Thread threadB=new Thread(
new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
synchronized (resourceA) {
log.info("ThreadB GET resourceA");
synchronized (resourceB) {
log.info("ThreadB GET resourceB");
try {
resourceA.wait();
} catch (InterruptedException e) {
log.error("resourceB release Lock fail");
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
);
threadA.start();
threadB.start();
threadA.join();
threadB.join();
}