• Java基本知识


    1. CGLIB动态代理:

     1 Enhancer enhancer = new Enhancer();
     2 enhancer.setSuperclass(SampleClass.class);
     3 enhancer.setCallback(new MethodInterceptor() {
     4     @Override
     5     public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
     6         System.out.println("before method run...");
     7         Object result = proxy.invokeSuper(obj, args);
     8         System.out.println("after method run...");
     9         return result;
    10     }
    11 });
    12 SampleClass sample = (SampleClass) enhancer.create();
    13 sample.test();

    注意:动态代理不能拦截final方法

    jdk动态代理:需要有顶层接口才能使用

    cglib动态代理:可以直接代理类,使用字节码技术,不能对 final类进行继承

    2. 字符串常量池:

    注意:在jdk1.7之前,字符串常量存储在方法区的PermGen Space。在jdk1.7之后,字符串常量重新被移到了堆中

    a. String a1 = "aa";      //先判断“aa”是否在常量池,如果在则直接引用,否则,在常量池中创建“aa”

    b. String a2 = new String("aa");     //在堆上创建字符串对象,如果常量池不存在aa,则常量池中创建aa

    c. String a3 = "a" + "a";     //jvm编译时会自动优化为String a3 = "aa";

    d. String a4 = a3.intern();    //intern方法会去常量池中查找该对象,如果对象存在则返回常量池对象,否则在常量池中创建对象(jdk7则在常量池中生成字符串的引用)

    备注:JDK 1.7后,intern方法还是会先去查询常量池中是否有已经存在,如果存在,则返回常量池中的引用,这一点与之前没有区别,区别在于,如果在常量池找不到对应的字符串,则不会再将字符串拷贝到常量池,而只是在常量池中生成一个对原字符串的引用。

    e. String a5 = new String("AA") + new String("BB");   //在堆上创建对象AA、BB和AABB,在常量池上创建常量AA和BB

    f. String a6 = "a1" + "a2";  //在常量池中创建“a1”、“a2”、“a1a2”

    3. HashMap死锁原因:

    HashMap在进行扩容时,需要将原链表内容拷贝到新的数组中,拷贝前A->B->C的链表,拷贝后会变为C->B->A,在多线程并发的情况下会出现环形链路,如果再调用get方法则会出现死循环

    4. ReentrantLoc相关知识:

    在性能上ReentrantLock和synchronized没有什么区别,但ReentrantLock相比synchronized而言功能更加丰富,使用起来更为灵活,也更适合复杂的并发场景。

       void lock();    //获取锁,若当前lock被其他线程获取;则此线程阻塞等待lock被释放

       boolean tryLock();   //尝试获取锁,如果获取成功,则返回true;

      void unlock();   //释放锁(加锁次数必须与解锁次数相同)

      Condition newCondition();    //返回一个绑定该lock的Condtion对象

    ReentrantLock 与 synchronized 的比较

    相同:ReentrantLock提供了synchronized类似的功能和内存语义。

    不同:

    (1)与synchronized相比,ReentrantLock提供了更多,更加全面的功能,具备更强的扩展性。例如:时间锁等候,可中断锁等候,锁投票。

    (2)ReentrantLock还提供了条件Condition,对线程的等待、唤醒操作更加详细和灵活,所以在多个条件变量和高度竞争锁的地方,ReentrantLock更加适合(下面会阐述Condition)。

    (3)ReentrantLock提供了可轮询的锁请求。它会尝试着去获取锁,如果成功则继续,否则可以等到下次运行时处理,而synchronized则一旦进入锁请求要么成功,要么一直阻塞,所以相比synchronized而言,ReentrantLock会不容易产生死锁些。

    (4)ReentrantLock支持更加灵活的同步代码块,但是使用synchronized时,只能在同一个synchronized块结构中获取和释放。注:ReentrantLock的锁释放一定要在finally中处理,否则可能会产生严重的后果。

    (5)ReentrantLock支持中断处理,且性能较synchronized会好些。

    参考:https://www.cnblogs.com/xiaoxi/p/7651360.html

      https://blog.csdn.net/u010013573/article/details/87266678

    5. 序列化:

    对象的序列化可以通过实现两种接口来实现,若实现的是Serializable接口,则所有的序列化将会自动进行,若实现的是Externalizable接口,则没有任何东西可以自动序列化,需要在writeExternal方法中进行手工指定所要序列化的变量,这与是否被transient修饰无关。

    6. 多线程控制:

    CountDownLatch  可以实现某个任务等待其他几个任务完成后执行

    CyclicBarrier    可以实现让一组线程等待至某个状态之后再全部同时执行

    Semaphore    用来控制同时访问的线程个数

      public void acquire()   用来获取一个许可,若无许可能够获得,则会一直等待,直到获得许可

      public void release()  用来释放许可。注意,在释放许可之前,必须先获获得许可

    7. ThreadLocal实现原理:

           在类Thread中持有一个ThreadLocal.ThreadLocalMap对象,ThreadLocal对象先获取到当前线程的ThreadLocalMap对象,然后set/get对应的值

      InheritableThreadLocal 能够继承父线程的数据(注意:线程池的情况下InheritableThreadLocal数据不会释放)

  • 相关阅读:
    JavaBean 与 EJB 的区别
    MFC选项卡的实现
    MFC的图片按钮
    windows 下使用 MinGW + msys 编译 ffmpeg
    在windows使用vs2008编译live555
    C89 和 C99 标准比较
    11.求二元查找树的镜像[MirrorOfBST]
    10.排序数组中和为给定值的两个数字[Find2NumbersWithGivenSum]
    9.链表中倒数第k个结点[FindReverseKthLinkedListNode]
    8.另类方法求1+2+...+n[AnotherMethodOfCalculateSumN]
  • 原文地址:https://www.cnblogs.com/wuan90/p/11227400.html
Copyright © 2020-2023  润新知