jdk8源码分析笔记1 --> Object.class

第一章节,不能再往前了!java

前言:缓存

学习jdk源码,提升本身的code能力ide

源码学习的过程是经过,对自身的提高远比贴吧来的更准确,更实用。源码分析

注:所有代码会在帖子最后面贴出学习

开山第一斧:Object.classui

学习思路,熟悉方法的使用和实现原理this

@Test
  public void testGetClass() {
    User user = new User();
    Class<? extends User> userClass = user.getClass();
    System.out.println(userClass.getName());
    System.out.println(userClass.getSimpleName());
    System.out.println(userClass.getTypeName());
    /**
     * ....能够获取更多信息
     * 执行结果
     * com.daly.demo.test.TestObject$User
     * User
     * com.daly.demo.test.TestObject$User
     */
  }
@Test
  public void testHashCode() {
    User user1 = new User(1, "jack");
    User user2 = new User(1, "jack");
    HashSet<User> set = new HashSet<>();
    set.add(user1);
    set.add(user2);
    System.out.println("user1.hashcode =" + user1.hashCode());
    System.out.println("user2.hashcode =" + user2.hashCode());
    System.out.println("uesr1.equals(user2) is " + user1.equals(user2));
    System.out.println("set.size = " + set.size());
    /**
     * 在使用HashMap,HashSet时,经过比较hahscode的值来判断是否相等
     * 运行结果
     * user1.hashcode =1023487453
     * user2.hashcode =1865127310
     * uesr1.equals(user2) is false
     * set.size = 2
     */
  }

仅重写了equals方法,再使用set时,没法判断重复对象,由于,他们的hashcode值不同,被认为是不一样的key,spa

@Test
  public void testHashCodeOverride() {
    UserOverride user1 = new UserOverride(1, "jack");
    UserOverride user2 = new UserOverride(1, "jack");
    HashSet<UserOverride> set = new HashSet<>();
    set.add(user1);
    set.add(user2);
    System.out.println("user1.hashcode =" + user1.hashCode());
    System.out.println("user2.hashcode =" + user2.hashCode());
    System.out.println("uesr1.equals(user2) is " + user1.equals(user2));
    System.out.println("set.size =" + set.size());
    /**
     * 在使用HashMap,HashSet时,经过比较hahscode的值来判断是否相等
     * 运行结果
     * user1.hashcode =1023487453
     * user2.hashcode =1865127310
     * uesr1.equals(user2) is true
     * set.size =2
     */
  }

同时重写equals和hashcode方法,代码以下:.net

@Test
  public void testHashCodeOverride() {
    UserOverride user1 = new UserOverride(1, "jack");
    UserOverride user2 = new UserOverride(1, "jack");
    HashSet<UserOverride> set = new HashSet<>();
    set.add(user1);
    set.add(user2);
    System.out.println("user1.hashcode =" + user1.hashCode());
    System.out.println("user2.hashcode =" + user2.hashCode());
    System.out.println("uesr1.equals(user2) is " + user1.equals(user2));
    System.out.println("set.size =" + set.size());
    /**
     * 在使用HashMap,HashSet时,经过比较hahscode的值来判断是否相等
     * 运行结果
     * user1.hashcode =3254238
     * user2.hashcode =3254238
     * uesr1.equals(user2) is true
     * set.size =1
     */
  }
//jdk源码的equals方法实现,是比较内存的地址,在比较继承
//在比较对象是否相等,须要重写这个方法,并且还要重写hashcode方法,缘由是set在判断对象是否已存在时,是经过对象的hashcode来判断的
public boolean equals(Object obj) {
    return (this == obj);
}
@Test
  public void testEquals() {
    int i1 = 127,i2 = 127;
    Integer ibox1 = 128, ibox2 = 128;
    System.out.println("int i1 = 127,i2 = 127;            --> i1 == i2            is " + (i1 == i2));
    System.out.println("Integer ibox1 = 128, ibox2 = 128; --> ibox1 == ibox2      is " + (ibox1 == ibox2));
    System.out.println("Integer ibox1 = 128, ibox2 = 128; --> ibox1.equals(ibox2) is " + ibox1.equals(ibox2));
    /**
     * 由于Integer在重写equals方法时,
     * 执行结果
     * int i1 = 127,i2 = 127;            --> i1 == i2            is true
     * Integer ibox1 = 128, ibox2 = 128; --> ibox1 == ibox2      is false
     * Integer ibox1 = 128, ibox2 = 128; --> ibox1.equals(ibox2) is true
     */
  }
//jdk8 源码部分
//在进行自动拆装箱时,编译器会使用Integer.valueof()来建立Integer实例。
//代码解释,先从缓存拿,没有拿到就建立一个Integer返回,Integer的取值范围在-128~127全部超过127时,就会出现陷阱了
public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}
@Test
  public void testCloneShallow() throws CloneNotSupportedException {
    Role role = new Role(1, "normal");
    User user = new User(1, "jack");
    user.setRole(role);
    User userClone;
    userClone = (User) user.clone();
    System.out.println("user.equals(userClone)                 is " + user.equals(userClone));
    System.out.println("user == userClone                      is " + (user == userClone));
    System.out.println( "user.getRole() == userClone.getRole() is " + (user.getRole() == userClone.getRole()));
    System.out.println("------------ 分割线 -----------");
    user.getRole().setRoleName(user.getRole().getRoleName().toUpperCase());
    System.out.println("user.getRole().getRoleName()      is "+user.getRole().getRoleName());
    System.out.println("userClone.getRole().getRoleName() is "+userClone.getRole().getRoleName());
    /**
     * 此处的user.clone()为浅拷贝,因此user和userClone的UserOverride是指向同一内存地址的对象
     * 执行结果
     * 由于User没有重写equals方法,因此 equals的结果跟== 都为false
     * user.equals(userClone)                 is false
     * user == userClone                      is false
     * user.getRole() == userClone.getRole() is true
     * ------------ 分割线 -----------
     * user.getRole().getRoleName()      is NORMAL
     * userClone.getRole().getRoleName() is NORMAL
     */
  }
@Test
public void testCloneDeep() throws CloneNotSupportedException {
  RoleOverride role = new RoleOverride(1, "normal");
  UserOverride user = new UserOverride(1, "jack");
  user.setRoleOverride(role);
  UserOverride userClone;
  userClone = (UserOverride) user.clone();
  System.out.println("user.equals(userClone)  is " + user.equals(userClone));
  System.out.println("user == userClone       is " + (user == userClone));
  System.out.println("they'er getUserOverride is " +
      (user.getRoleOverride() == userClone.getRoleOverride()));
  System.out.println("------------ 分割线 -----------");
  user.getRoleOverride().setRoleName(user.getRoleOverride().getRoleName().toUpperCase());
  System.out.println("user.getRole().getRoleName() is "+user.getRoleOverride().getRoleName());
  System.out.println("userClone.getRole().getRoleName() is "+userClone.getRoleOverride().getRoleName());
  /**
   * 此处的user.clone()为浅拷贝,因此user和userClone的UserOverride是指向同一内存地址的对象
   * 执行结果
   * 由于 RoleOverride 重写了equals方法,因此 equals的结果为true, == 结果为 false
   * user.equals(userClone)  is true
   * user == userClone       is false
   * they'er getUserOverride is false
   * ------------ 分割线 -----------
   * user.getRole().getRoleName() is NORMAL
   * userClone.getRole().getRoleName() is normal
   */
}

深度clone的关键代码以下:线程

@Override
protected Object clone() throws CloneNotSupportedException {
  Object clone = super.clone();
  RoleOverride roleOverride = ((UserOverride)clone).getRoleOverride();
  ((UserOverride)clone).setRoleOverride((RoleOverride) roleOverride.clone());
  return clone;
}

jdk8 的Object的toString方法的源码以下

//返回的是className@哈希值
//在建立类时,须要重写这个方法
public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

notify唤醒了其中一个等待的线程,

/**
   * 来自博客 https://blog.csdn.net/u014658905/article/details/81035870
   */
  @Test
  public void testNotify() throws InterruptedException {
    final NotificationTest test = new NotificationTest();
    Runnable waitTask = () -> {
      try {
        test.shouldGo();
      } catch (InterruptedException ex) {
        System.out.println(ex.getMessage());
      }
      System.out.println(Thread.currentThread().getName() + " finished Execution");
    };
    Runnable notifyTask = () -> {
      test.go2();
      System.out.println(Thread.currentThread().getName() + " finished Execution");
    };
    Thread t1 = new Thread(waitTask, "WT1"); //will wait
    Thread t2 = new Thread(waitTask, "WT2"); //will wait
    Thread t3 = new Thread(waitTask, "WT3"); //will wait
    Thread t4 = new Thread(notifyTask, "NT1"); //will notify
    //starting all waiting thread
    t1.start();
    t2.start();
    t3.start();
    //pause to ensure all waiting thread started successfully
    sleep(200);
    //starting notifying thread
    t4.start();
    /**
     * 运行结果
     * WT1 is going to wait on this object
     * WT2 is going to wait on this object
     * WT3 is going to wait on this object
     * NT1 is going to notify all or one thread waiting on this object
     * NT1 finished Execution
     * WT1 is woken up
     * WT1 finished Execution
     */
  }

notifyAll唤醒了所有等待的线程

/**
   * 来自博客 https://blog.csdn.net/u014658905/article/details/81035870
   */
  @Test
  public void testNotifyAll() throws InterruptedException {
    final NotificationTest test = new NotificationTest();
    Runnable waitTask = () -> {
      try {
        test.shouldGo();
      } catch (InterruptedException ex) {
        System.out.println(ex.getMessage());
      }
      System.out.println(Thread.currentThread().getName() + " finished Execution");
    };
    Runnable notifyTask = () -> {
      test.go();
      System.out.println(Thread.currentThread().getName() + " finished Execution");
    };
    Thread t1 = new Thread(waitTask, "WT1"); //will wait
    Thread t2 = new Thread(waitTask, "WT2"); //will wait
    Thread t3 = new Thread(waitTask, "WT3"); //will wait
    Thread t4 = new Thread(notifyTask, "NT1"); //will notify
    //starting all waiting thread
    t1.start();
    t2.start();
    t3.start();
    //pause to ensure all waiting thread started successfully
    sleep(200);
    //starting notifying thread
    t4.start();
    /**
     * 运行结果
     * WT1 is going to wait on this object
     * WT2 is going to wait on this object
     * WT3 is going to wait on this object
     * NT1 is going to notify all or one thread waiting on this object
     * NT1 finished Execution
     * WT3 is woken up
     * WT3 finished Execution
     * WT2 is woken up
     * WT2 is going to wait on this object
     * WT1 is woken up
     * WT1 is going to wait on this object
     */
  }
/**
   * 除了耗时完成后自动唤醒,还能够被notify和notifyAll唤醒
   * notify和notifyAll唤醒方式,如上面的例子所示
   * @throws InterruptedException
   */
  @Test
  public void testWait() throws InterruptedException {
    Runnable myThread = () -> {
      synchronized (this) {
        try {
          System.out.println("myThread start at "+ new SimpleDateFormat("mm:ss").format(new Date()));
          //wait(5000);//5秒钟以后唤醒当前线程.继续执行
          wait();//一直等待
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        System.out.println("myThread run end");
      }
    };

    Thread t1 = new Thread(myThread, "t1"); //will wait
    synchronized (t1) {
      t1.start();
      t1.wait(2000); //2秒钟以后,唤醒了main线程继续执行
      //t1.wait(2000,1000);//1000000*2000+1000 毫微秒钟以后,唤醒了main线程,彻底体现不出来这第二个参数的意义
      //t1.wait();//mian线程一直等待,没有被其余线程唤醒
      System.out.println("mainThread wake up at "+ new SimpleDateFormat("mm:ss").format(new Date()));
      System.out.println("main run end");
    }
    /**
     * 运行结果以下
     * 当myThread被提早唤醒时,后面的代码不会被执行
     * myThread start at 38:57
     * myThread run end
     * mainThread wake up at 39:02
     * main run end
     * 或
     *myThread start at 41:52
     * mainThread wake up at 41:54
     * main run end
     */
  }

最后一个方法就是finalize

/**
   * 很经典的GC回收机制实例
   */
  @Test
  public void testFinalize() throws InterruptedException {
    // 新建对象,由于SAVE_HOOK指向这个对象,对象此时的状态是(reachable,unfinalized)
    GC.SAVE_HOOK = new GC();
    //将SAVE_HOOK设置成null,此时刚才建立的对象就不可达了,由于没有句柄再指向它了,对象此时状态是(unreachable,unfinalized)
    GC.SAVE_HOOK = null;
    //强制系统执行垃圾回收,系统发现刚才建立的对象处于unreachable状态,并检测到这个对象的类覆盖了finalize方法,所以把这个对象放入F-Queue队列,由低优先级线程执行它的finalize方法,此时对象的状态变成(unreachable, finalizable)或者是(finalizer-reachable,finalizable)
    System.gc();
    // sleep,目的是给低优先级线程从F-Queue队列取出对象并执行其finalize方法提供机会。在执行完对象的finalize方法中的super.finalize()时,对象的状态变成(unreachable,finalized)状态,但接下来在finalize方法中又执行了SAVE_HOOK = this;这句话,又有句柄指向这个对象了,对象又可达了。所以对象的状态又变成了(reachable, finalized)状态。
    Thread.sleep(500);
    // 这里楼主说对象处于(reachable,finalized)状态应该是合理的。对象的finalized方法被执行了,所以是finalized状态。又由于在finalize方法是执行了SAVE_HOOK=this这句话,原本是unreachable的对象,又变成reachable了。
    if (null != GC.SAVE_HOOK) { //此时对象应该处于(reachable, finalized)状态
      // 这句话会输出,注意对象由unreachable,通过finalize复活了。
      System.out.println("Yes , I am still alive");
    } else {
      System.out.println("No , I am dead");
    }
    // 再一次将SAVE_HOOK放空,此时刚才复活的对象,状态变成(unreachable,finalized)
    GC.SAVE_HOOK = null;
    // 再一次强制系统回收垃圾,此时系统发现对象不可达,虽然覆盖了finalize方法,但已经执行过了,所以直接回收。
    System.gc();
    // 为系统回收垃圾提供机会
    Thread.sleep(500);
    if (null != GC.SAVE_HOOK) {
      // 这句话不会输出,由于对象已经完全消失了。
      System.out.println("Yes , I am still alive");
    } else {
      System.out.println("No , I am dead");
    }
  }

Object.class的全部方法都举了栗子,欢迎你们指正。

补充: 比较obj.hashcode 和 System.identityHashCode(obj) 的区别

/**
   * 比较obj.hashCode 和系统的  System.identityHashCode(obj)的不一样
   * obj.hashCode比较的是值,是obj重写的hashCode方法,
   * System.identityHashCode是将obj的存储位置转换成为hashCode
   */
  @Test
  public void testSystemHashCode() throws CloneNotSupportedException {
    User u1 = new User(1,"jack");
    User u2 = new User(1,"jack");
    Role role = new Role(1,"normal");
    u1.setRole(role);
    u2.setRole(role);
    User u1Clone = (User) u1.clone();//此处为浅拷贝,user.getRole指向的是同一个内存地址
    System.out.println("System.identityHashCode(u1)=="+System.identityHashCode(u1.getRole()));
    System.out.println("System.identityHashCode(u1Clone)=="+System.identityHashCode(u1Clone.getRole()));
    System.out.println("System.identityHashCode(u2)=="+System.identityHashCode(u2.getRole()));
    System.out.println("--------------- 分割线 --------------");
    UserOverride u3 = new UserOverride(1, "jack");
    UserOverride u4 = new UserOverride(1, "jack");
    RoleOverride r1 = new RoleOverride(1,"normal");
    u3.setRoleOverride(r1);
    u4.setRoleOverride(r1);
    //此处是深克隆,u3.getRoleOverride是指向不一样的物理地址
    UserOverride u3Clone = (UserOverride) u3.clone();
    System.out.println("System.identityHashCode(u3)=="+System.identityHashCode(u3.getRoleOverride()));
    System.out.println("System.identityHashCode(u3Clone)=="+System.identityHashCode(u3Clone.getRoleOverride()));
    System.out.println("System.identityHashCode(u4)=="+System.identityHashCode(u4.getRoleOverride()));

    /**
     * 运行结果
     * System.identityHashCode(u1)==1023487453
     * System.identityHashCode(u1Clone)==1023487453
     * System.identityHashCode(u2)==1023487453
     * --------------- 分割线 --------------
     * System.identityHashCode(u3)==1865127310
     * System.identityHashCode(u3Clone)==515132998
     * System.identityHashCode(u4)==1865127310
     */
  }

 

 

 

下面是所有源码,写的都是内部类+@Test注解,能够直接运行

import static java.lang.Thread.sleep;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import org.junit.Test;

public class TestObject {

  @Test
  public void testGetClass() {
    User user = new User();
    Class<? extends User> userClass = user.getClass();
    System.out.println(userClass.getName());
    System.out.println(userClass.getSimpleName());
    System.out.println(userClass.getTypeName());
    /**
     * ....能够获取更多信息
     * 执行结果
     * com.daly.demo.test.TestObject$User
     * User
     * com.daly.demo.test.TestObject$User
     */
  }

  @Test
  public void testHashCode() {
    User user1 = new User(1, "jack");
    User user2 = new User(1, "jack");
    HashSet<User> set = new HashSet<>();
    set.add(user1);
    set.add(user2);
    System.out.println("user1.hashcode =" + user1.hashCode());
    System.out.println("user2.hashcode =" + user2.hashCode());
    System.out.println("uesr1.equals(user2) is " + user1.equals(user2));
    System.out.println("set.size = " + set.size());
    /**
     * 在使用HashMap,HashSet时,经过比较hahscode的值来判断是否相等
     * 运行结果
     * user1.hashcode =1023487453
     * user2.hashcode =1865127310
     * uesr1.equals(user2) is false
     * set.size = 2
     */
  }

  @Test
  public void testHashCodeOverride() {
    UserOverride user1 = new UserOverride(1, "jack");
    UserOverride user2 = new UserOverride(1, "jack");
    HashSet<UserOverride> set = new HashSet<>();
    set.add(user1);
    set.add(user2);
    System.out.println("user1.hashcode =" + user1.hashCode());
    System.out.println("user2.hashcode =" + user2.hashCode());
    System.out.println("uesr1.equals(user2) is " + user1.equals(user2));
    System.out.println("set.size =" + set.size());
    /**
     * 在使用HashMap,HashSet时,经过比较hahscode的值来判断是否相等
     * 运行结果
     * user1.hashcode =3254238
     * user2.hashcode =3254238
     * uesr1.equals(user2) is true
     * set.size =1
     */
  }


  @Test
  public void testEquals() {
    int i1 = 127, i2 = 127;
    Integer ibox1 = 128, ibox2 = 128;
    System.out
        .println("int i1 = 127,i2 = 127;            --> i1 == i2            is " + (i1 == i2));
    System.out.println(
        "Integer ibox1 = 128, ibox2 = 128; --> ibox1 == ibox2      is " + (ibox1 == ibox2));
    System.out.println(
        "Integer ibox1 = 128, ibox2 = 128; --> ibox1.equals(ibox2) is " + ibox1.equals(ibox2));
    /**
     * 由于Integer在重写equals方法时,
     * 执行结果
     * int i1 = 127,i2 = 127;            --> i1 == i2            is true
     * Integer ibox1 = 128, ibox2 = 128; --> ibox1 == ibox2      is false
     * Integer ibox1 = 128, ibox2 = 128; --> ibox1.equals(ibox2) is true
     */
  }

  @Test
  public void testCloneShallow() throws CloneNotSupportedException {
    Role role = new Role(1, "normal");
    User user = new User(1, "jack");
    user.setRole(role);
    User userClone;
    userClone = (User) user.clone();
    System.out.println("user.equals(userClone)                 is " + user.equals(userClone));
    System.out.println("user == userClone                      is " + (user == userClone));
    System.out.println(
        "user.getRole() == userClone.getRole() is " + (user.getRole() == userClone.getRole()));
    System.out.println("------------ 分割线 -----------");
    user.getRole().setRoleName(user.getRole().getRoleName().toUpperCase());
    System.out.println("user.getRole().getRoleName()      is " + user.getRole().getRoleName());
    System.out.println("userClone.getRole().getRoleName() is " + userClone.getRole().getRoleName());
    /**
     * 此处的user.clone()为浅拷贝,因此user和userClone的UserOverride是指向同一内存地址的对象
     * 执行结果
     * 由于User没有重写equals方法,因此 equals的结果跟== 都为false
     * user.equals(userClone)                 is false
     * user == userClone                      is false
     * user.getRole() == userClone.getRole() is true
     * ------------ 分割线 -----------
     * user.getRole().getRoleName()      is NORMAL
     * userClone.getRole().getRoleName() is NORMAL
     */
  }

  @Test
  public void testCloneDeep() throws CloneNotSupportedException {
    RoleOverride role = new RoleOverride(1, "normal");
    UserOverride user = new UserOverride(1, "jack");
    user.setRoleOverride(role);
    UserOverride userClone;
    userClone = (UserOverride) user.clone();
    System.out.println("user.equals(userClone)  is " + user.equals(userClone));
    System.out.println("user == userClone       is " + (user == userClone));
    System.out.println("they'er getUserOverride is " +
        (user.getRoleOverride() == userClone.getRoleOverride()));
    System.out.println("------------ 分割线 -----------");
    user.getRoleOverride().setRoleName(user.getRoleOverride().getRoleName().toUpperCase());
    System.out.println("user.getRole().getRoleName() is " + user.getRoleOverride().getRoleName());
    System.out.println(
        "userClone.getRole().getRoleName() is " + userClone.getRoleOverride().getRoleName());
    /**
     * 此处的user.clone()为浅拷贝,因此user和userClone的UserOverride是指向同一内存地址的对象
     * 执行结果
     * 由于 RoleOverride 重写了equals方法,因此 equals的结果为true, == 结果为 false
     * user.equals(userClone)  is true
     * user == userClone       is false
     * they'er getUserOverride is false
     * ------------ 分割线 -----------
     * user.getRole().getRoleName() is NORMAL
     * userClone.getRole().getRoleName() is normal
     */
  }

  /**
   * 来自博客 https://blog.csdn.net/u014658905/article/details/81035870
   */
  @Test
  public void testNotifyAll() throws InterruptedException {
    final NotificationTest test = new NotificationTest();
    Runnable waitTask = () -> {
      try {
        test.shouldGo();
      } catch (InterruptedException ex) {
        System.out.println(ex.getMessage());
      }
      System.out.println(Thread.currentThread().getName() + " finished Execution");
    };
    Runnable notifyTask = () -> {
      test.go();
      System.out.println(Thread.currentThread().getName() + " finished Execution");
    };
    Thread t1 = new Thread(waitTask, "WT1"); //will wait
    Thread t2 = new Thread(waitTask, "WT2"); //will wait
    Thread t3 = new Thread(waitTask, "WT3"); //will wait
    Thread t4 = new Thread(notifyTask, "NT1"); //will notify
    //starting all waiting thread
    t1.start();
    t2.start();
    t3.start();
    //pause to ensure all waiting thread started successfully
    sleep(200);
    //starting notifying thread
    t4.start();
    /**
     * 运行结果
     * WT1 is going to wait on this object
     * WT2 is going to wait on this object
     * WT3 is going to wait on this object
     * NT1 is going to notify all or one thread waiting on this object
     * NT1 finished Execution
     * WT3 is woken up
     * WT3 finished Execution
     * WT2 is woken up
     * WT2 is going to wait on this object
     * WT1 is woken up
     * WT1 is going to wait on this object
     */
  }

  /**
   * 来自博客 https://blog.csdn.net/u014658905/article/details/81035870
   */
  @Test
  public void testNotify() throws InterruptedException {
    final NotificationTest test = new NotificationTest();
    Runnable waitTask = () -> {
      try {
        test.shouldGo();
      } catch (InterruptedException ex) {
        System.out.println(ex.getMessage());
      }
      System.out.println(Thread.currentThread().getName() + " finished Execution");
    };
    Runnable notifyTask = () -> {
      test.go2();
      System.out.println(Thread.currentThread().getName() + " finished Execution");
    };
    Thread t1 = new Thread(waitTask, "WT1"); //will wait
    Thread t2 = new Thread(waitTask, "WT2"); //will wait
    Thread t3 = new Thread(waitTask, "WT3"); //will wait
    Thread t4 = new Thread(notifyTask, "NT1"); //will notify
    //starting all waiting thread
    t1.start();
    t2.start();
    t3.start();
    //pause to ensure all waiting thread started successfully
    sleep(200);
    //starting notifying thread
    t4.start();
    /**
     * 运行结果
     * WT1 is going to wait on this object
     * WT2 is going to wait on this object
     * WT3 is going to wait on this object
     * NT1 is going to notify all or one thread waiting on this object
     * NT1 finished Execution
     * WT1 is woken up
     * WT1 finished Execution
     */
  }

  /**
   * 除了耗时完成后自动唤醒,还能够被notify和notifyAll唤醒 notify和notifyAll唤醒方式,如上面的例子所示
   */
  @Test
  public void testWait() throws InterruptedException {
    Runnable myThread = () -> {
      synchronized (this) {
        try {
          System.out
              .println("myThread start at " + new SimpleDateFormat("mm:ss").format(new Date()));
          //wait(5000);//5秒钟以后唤醒当前线程.继续执行
          wait();//一直等待
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        System.out.println("myThread run end");
      }
    };

    Thread t1 = new Thread(myThread, "t1"); //will wait
    synchronized (t1) {
      t1.start();
      t1.wait(2000); //2秒钟以后,唤醒了main线程继续执行
      //t1.wait(2000,1000);//1000000*2000+1000 毫微秒钟以后,唤醒了main线程,彻底体现不出来这第二个参数的意义
      //t1.wait();//mian线程一直等待,没有被其余线程唤醒
      System.out
          .println("mainThread wake up at " + new SimpleDateFormat("mm:ss").format(new Date()));
      System.out.println("main run end");
    }
    /**
     * 运行结果以下
     * 当myThread被提早唤醒时,后面的代码不会被执行
     * myThread start at 38:57
     * myThread run end
     * mainThread wake up at 39:02
     * main run end
     * 或
     *myThread start at 41:52
     * mainThread wake up at 41:54
     * main run end
     */
  }


  /**
   * 很经典的GC回收机制实例
   */
  @Test
  public void testFinalize() throws InterruptedException {
    // 新建对象,由于SAVE_HOOK指向这个对象,对象此时的状态是(reachable,unfinalized)
    GC.SAVE_HOOK = new GC();
    //将SAVE_HOOK设置成null,此时刚才建立的对象就不可达了,由于没有句柄再指向它了,对象此时状态是(unreachable,unfinalized)
    GC.SAVE_HOOK = null;
    //强制系统执行垃圾回收,系统发现刚才建立的对象处于unreachable状态,并检测到这个对象的类覆盖了finalize方法,所以把这个对象放入F-Queue队列,由低优先级线程执行它的finalize方法,此时对象的状态变成(unreachable, finalizable)或者是(finalizer-reachable,finalizable)
    System.gc();
    // sleep,目的是给低优先级线程从F-Queue队列取出对象并执行其finalize方法提供机会。在执行完对象的finalize方法中的super.finalize()时,对象的状态变成(unreachable,finalized)状态,但接下来在finalize方法中又执行了SAVE_HOOK = this;这句话,又有句柄指向这个对象了,对象又可达了。所以对象的状态又变成了(reachable, finalized)状态。
    Thread.sleep(500);
    // 这里楼主说对象处于(reachable,finalized)状态应该是合理的。对象的finalized方法被执行了,所以是finalized状态。又由于在finalize方法是执行了SAVE_HOOK=this这句话,原本是unreachable的对象,又变成reachable了。
    if (null != GC.SAVE_HOOK) { //此时对象应该处于(reachable, finalized)状态
      // 这句话会输出,注意对象由unreachable,通过finalize复活了。
      System.out.println("Yes , I am still alive");
    } else {
      System.out.println("No , I am dead");
    }
    // 再一次将SAVE_HOOK放空,此时刚才复活的对象,状态变成(unreachable,finalized)
    GC.SAVE_HOOK = null;
    // 再一次强制系统回收垃圾,此时系统发现对象不可达,虽然覆盖了finalize方法,但已经执行过了,所以直接回收。
    System.gc();
    // 为系统回收垃圾提供机会
    Thread.sleep(500);
    if (null != GC.SAVE_HOOK) {
      // 这句话不会输出,由于对象已经完全消失了。
      System.out.println("Yes , I am still alive");
    } else {
      System.out.println("No , I am dead");
    }
  }
 /**
   * 比较obj.hashCode 和系统的  System.identityHashCode(obj)的不一样
   * obj.hashCode比较的是值,是obj重写的hashCode方法,
   * System.identityHashCode是将obj的存储位置转换成为hashCode
   */
  @Test
  public void testSystemHashCode() throws CloneNotSupportedException {
    User u1 = new User(1,"jack");
    User u2 = new User(1,"jack");
    Role role = new Role(1,"normal");
    u1.setRole(role);
    u2.setRole(role);
    User u1Clone = (User) u1.clone();//此处为浅拷贝,user.getRole指向的是同一个内存地址
    System.out.println("System.identityHashCode(u1)=="+System.identityHashCode(u1.getRole()));
    System.out.println("System.identityHashCode(u1Clone)=="+System.identityHashCode(u1Clone.getRole()));
    System.out.println("System.identityHashCode(u2)=="+System.identityHashCode(u2.getRole()));
    System.out.println("--------------- 分割线 --------------");
    UserOverride u3 = new UserOverride(1, "jack");
    UserOverride u4 = new UserOverride(1, "jack");
    RoleOverride r1 = new RoleOverride(1,"normal");
    u3.setRoleOverride(r1);
    u4.setRoleOverride(r1);
    //此处是深克隆,u3.getRoleOverride是指向不一样的物理地址
    UserOverride u3Clone = (UserOverride) u3.clone();
    System.out.println("System.identityHashCode(u3)=="+System.identityHashCode(u3.getRoleOverride()));
    System.out.println("System.identityHashCode(u3Clone)=="+System.identityHashCode(u3Clone.getRoleOverride()));
    System.out.println("System.identityHashCode(u4)=="+System.identityHashCode(u4.getRoleOverride()));

    /**
     * 运行结果
     * System.identityHashCode(u1)==1023487453
     * System.identityHashCode(u1Clone)==1023487453
     * System.identityHashCode(u2)==1023487453
     * --------------- 分割线 --------------
     * System.identityHashCode(u3)==1865127310
     * System.identityHashCode(u3Clone)==515132998
     * System.identityHashCode(u4)==1865127310
     */
  }

  private class User implements Cloneable {

    private int userId;
    private String userName;
    private Role role;

    User() {
    }

    User(int userId, String userName) {
      this.userId = userId;
      this.userName = userName;
    }

    Role getRole() {
      return role;
    }

    void setRole(Role role) {
      this.role = role;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
      return super.clone();
    }
  }

  private class UserOverride implements Cloneable {

    private int userId;
    private String userName;
    private RoleOverride roleOverride;

    UserOverride(int userId, String userName) {
      this.userId = userId;
      this.userName = userName;
    }

    RoleOverride getRoleOverride() {
      return roleOverride;
    }

    void setRoleOverride(RoleOverride roleOverride) {
      this.roleOverride = roleOverride;
    }

    @Override
    public int hashCode() {
      return userName.hashCode() ^ userId;
    }

    @Override
    public boolean equals(Object obj) {
      if (obj == null) {
        return false;
      }
      //若是是同一个对象返回true,反之返回false
      if (this == obj) {
        return true;
      }
      //判断是否类型相同
      if (this.getClass() != obj.getClass()) {
        return false;
      }
      UserOverride person = (UserOverride) obj;
      return userName.equals(person.userName) && userId == person.userId;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
      Object clone = super.clone();
      RoleOverride roleOverride = ((UserOverride) clone).getRoleOverride();
      ((UserOverride) clone).setRoleOverride((RoleOverride) roleOverride.clone());
      return clone;
    }
  }

  private class Role {

    private int roleId;
    private String roleName;

    Role(int roleId, String roleName) {
      this.roleId = roleId;
      this.roleName = roleName;
    }

    String getRoleName() {
      return roleName;
    }

    void setRoleName(String roleName) {
      this.roleName = roleName;
    }
  }

  private class RoleOverride implements Cloneable {

    private int roleId;
    private String roleName;

    RoleOverride(int roleId, String roleName) {
      this.roleId = roleId;
      this.roleName = roleName;
    }

    String getRoleName() {
      return roleName;
    }

    void setRoleName(String roleName) {
      this.roleName = roleName;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
      return super.clone();
    }
  }

  private class NotificationTest {

    private volatile boolean go = false;

    synchronized void shouldGo() throws InterruptedException {
      while (go != true) {
        System.out.println(Thread.currentThread().getName()
            + " is going to wait on this object");
        wait(); //release lock and reacquires on wakeup
        System.out.println(Thread.currentThread().getName() + " is woken up");
      }
      go = false; //resetting condition
    }

    /*
     * both shouldGo() and go() are locked on current object referenced by "this" keyword
     */
    synchronized void go() {
      while (go == false) {
        System.out.println(Thread.currentThread().getName()
            + " is going to notify all or one thread waiting on this object");

        go = true; //making condition true for waiting thread
        //notify(); // only one out of three waiting thread WT1, WT2,WT3 will woke up
        notifyAll(); // all waiting thread  WT1, WT2,WT3 will woke up
      }

    }

    synchronized void go2() {
      while (go == false) {
        System.out.println(Thread.currentThread().getName()
            + " is going to notify all or one thread waiting on this object");

        go = true; //making condition true for waiting thread
        notify(); // only one out of three waiting thread WT1, WT2,WT3 will woke up
        //notifyAll(); // all waiting thread  WT1, WT2,WT3 will woke up
      }

    }
  }

  private static class GC {

    static GC SAVE_HOOK = null;

    @Override
    protected void finalize() throws Throwable {
      super.finalize();
      System.out.println("execute method finalize()");
      // 这句话让对象的状态由unreachable变成reachable,就是对象复活
      SAVE_HOOK = this;
    }
  }

}

下一章节传送门 --> jdk8源码分析笔记1 --> Object.class

相关文章
相关标签/搜索