ReZero's Utopia.

Java tricks

Word count: 613Reading time: 2 min
2021/03/04 Share
  1. 通过块来进行标量复用方便回收。注意的是在 未经过JIT编译前且块后未对局部变量进行读写,则可能仍然无法回收。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Hello{
public void reuse(){
{
int[] a = new int[1];
}
int b = 0; // b 可以复用a的局部变量表槽位
System.gc(); //此时a被销毁,故可以被GC回收,如果取掉上行,那么a虽然离开作用域但仍然在局部表中,不可以被GC
}

public void notReuse(){
int a = 0;
int b = 0; //a, b 均到了作用域末尾, b 不可以复用a的局部变量表槽位
}
}
  1. 通过扫描 WAIT 线程,减少不必要的WAIT 线程 进而减少 WAIT到RUNNABLE 状态发生的上下文切换造成的性能损耗

  2. Collection.toArray 会转换为 Object 数组,因此最好穿个额外的参数 比如 new String[0],这样可以表明类型,还不占用空间

  3. 协变与逆变: PECS producer extends & consumer super <? super Apple> 限定的是下界,即扔进去的都是 Apple 的子类,
    这样就可以取的时候用 Apple 引用取,但如果扔进去 Apple 的父类,取的时候就不知道是哪个辈,可能用 Apple 爹持有了Apple 爷, Java 不许子类持有父类,因而不允许。
    同样的 <? extends Apple> 限定的是 Apple 上界,因为上界是 Apple了,那么自然可以用任意的 Apple 及 Apple 的爹爷辈来取;但不能往里面放 Apple 的儿辈。

    1
    2
    3
    4
    class SelfBounded<T extends SelfBounded<T>> {

    }
    // 子类重写父类方法,非泛型只能重载
  4. BatchInsert: 考虑生成字节码生成 toString 等作为批量插入values预生成方案检测sql长度等, 插入的多线程要逼近IO前提,而不是无脑的加,高于DB磁盘等的IO限制是无意义的加。侧重IO
    时要考虑下协程的使用,一般来说协程在IO
    方面的并发效率是优于线程的。既然考虑了线程池,线程池的参数也就需要考量了,基本做可以做成配置中心动态发布生效的效果,如果能达到监控业务场景合理自动调整配置最好。对于队列,考虑要用同步队列比较好,这样没有任务被缓存下来,所有的任务都立刻得到执行,效果自然会拔高。

CATALOG