java性能调优记录

五、设计模式调优

单例模式

最简单的单例模式及问题分析

// 懒汉模式
public final class Singleton {
private static Singleton instance= null;// 不实例化
private Singleton(){

if (instance != null) {
throw new RuntimeException("Use getInstance() method to get the single instance of this class.");
}

}// 构造函数
public static Singleton getInstance(){// 通过该函数向整个系统提供实例
if(null == instance){// 当 instance 为 null 时,则实例化对象,否则直接返回对象
instance = new Singleton();// 实例化对象
}
return instance;// 返回已存在的对象
}
}

问题分析:存在多次实例化的可能,多个线程同时修改不同单例对象可能导致数据不一致,因为单例对象可能持有计数器或者配置项等。

先创建的对象会不会被jvm垃圾回收?

可能会,前提是没有被其他对象引用,如创建并使用他的线程结束,该对象就不会被引用,下一次垃圾回收就会回收掉。

双重检查方式:

// 懒汉模式 + synchronized 同步锁 + double-check
public final class Singleton {
private volatile static Singleton instance= null;// 不实例化
private Singleton(){

if (instance != null) {
throw new RuntimeException("Use getInstance() method to get the single instance of this class.");
}

}// 构造函数
public static Singleton getInstance(){// 加同步锁,通过该函数向整个系统提供实例
if(null == instance){// 第一次判断,当 instance 为 null 时,则实例化对象,否则直接返回对象
synchronized (Singleton.class){// 同步锁
if(null == instance){// 第二次判断
instance = new Singleton();// 实例化对象
}
}
}
return instance;// 返回已存在的对象
}
}

双重检查模式的变量需要用volatile,volatile有两个作用:可见性,禁止指令重排序。

 静态内部类方式:

// 懒汉模式 内部类实现
public final class Singleton {

// 构造函数
private Singleton() {

if (InnerSingleTon.instance != null) {
throw new RuntimeException("Use getInstance() method to get the single instance of this class.");
}

}
// 内部类实现
public static class InnerSingleton {
private static Singleton instance=new Singleton();// 自行创建实例
}

public static Singleton getInstance() {
return InnerSingleton.instance;// 返回内部类中的静态变量
}
}

静态内部类和外部类的加载是独立的,外部类被加载时,静态内部类不会被立即加载。静态内部类只有在被主动引用时(例如创建静态内部类的实例或访问其静态成员)才会被加载。同样地,当静态内部类被加载时,它也不会导致外部类重新加载或初始化。

 装饰器模式

 六、数据库性能调优

快照读:当执行普通的select时,mysql不会加锁,而是读取数据库快照,在整个事务生命周期都是获取同一个快照数据,不糊收到其他事务更新或插入影响。快照并不是事务开始时的快照,而是第一次普通查询时被锁定的快照。

但是并不是每次查询结果不会变,如事务B插入一条原本不存在的数据,事务A修改了这条数据,此时事务A再查询是可以查到的。

当前读:当读取的是需要加锁的的操作,读取的是当前最新数据,当前读会阻止其他事务对被锁住的数据进行修改,并确保你看到的是最新的、当前事务的状态。

  • SELECT ... FOR UPDATE
  • SELECT ... LOCK IN SHARE MODE
  • UPDATEDELETE

间隙锁:需要注意mysql查询又间隙锁,即使只查询一条数据如order_no=4,数据分布是1,3,6,8,那么会锁定3到6之间的间隙,这种操作可以防止3-6之间的幻读。但是大于6的数据如7,20都是可以在另一个事务B中正常插入的,并且事务A中可以查到。

 分库分表:

分为水平拆分和垂直拆分:水平拆分是把数据分布在不同库上,垂直拆分是指把表字段再进行拆分。

分布式锁:redis官方推出的redisson框架。

 

posted @   高石柯南  阅读(6)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示