既然单例里有个静态实例对象,为什么不直接使用静态类?静态变量是在内存常驻的么?GC会不会销毁?多线程访问单例的安全问题?
编译期绑定称为静态绑定,在java中只有private,final,static和构造方法是静态绑定,动态绑定在运行时根据具体的对象的类型来绑定。
在方法的第一次加载时,无论静态方法和非静态方法,虽然都已经在Method Table中分配了,但非静态方法在分配时,会考虑到他的父类,一直到Object为止,
也会把父类的方法和字段都分配,所以非静态方法在分配上,有个向上查找的过程,比静态方法要复杂的多,但第一次载入后他们就没有差异了。
2.override的区别,静态方法是不能被覆盖的,这样就导致其没有太多的灵活性,另一方面可以通过继承的方式覆盖单例类中定义的方法,就是说单例更能
面向对象,提供不同的实现。
3.如果是一个非常重的对象。单例可以延迟加载,但静态类没有这样的优势,它始终保持着被热切加载的状态。
4.对于维护状态信息,单例则比静态类更适合,因为静态类中静态方法只能使用静态变量,比较容易产生bug。
静态变量是随着类的加载而加载,静态变量一旦被加载到内存,在这个类被卸载之前,它就一直存在,而类通常是在应用程序结束时才会被卸载,
所以说静态变量是内存常驻。GC不会被销毁。
什么是类的加载,类什么时候被加载呢,当程序主动使用到某个类时,如果该类还未被加载到内存中,系统会通过加载,连接,初始化三个步骤
对类进行初始化,JVM会连续完成这三个步骤,也把这三个步骤称为类加载或类初始化。
懒汉式的单例可通过sychronized同步方法解决,饿汉式可通过双重校验琐来解决,就是将单例对象声明为volatile类型,通过两次判断对象是否为空以及使用同步方法块
来解决线程的安全问题.代码如下:
- public class Singleton {
- private volatile static Singleton singleton;
- private Singleton (){}
- public static Singleton getSingleton() {
- if (singleton == null) {
- synchronized (Singleton.class) {
- if (singleton == null) {
- singleton = new Singleton();
- }
- }
- }
- return singleton;
- }
- }