源码系列——JDK 源码(1)——Object

73 阅读4分钟

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();

    }