单例模式
package singleton.type1;
/*所谓单例设计模式,就是采取一定的方法在整个软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得该对象实例的方法
* */
public class SingleTest01 {
public static void main(String[] args) {
/*饿汉式*/
Singleton instance = Singleton.getInstance();
Singleton instance1 = Singleton.getInstance();
System.out.println(instance==instance1);
System.out.println(instance.hashCode());
System.out.println(instance1.hashCode());
}
}
/*优缺点分析
* 优点:写法比较简单,就是在类装载的时候就完成了实例化。避免了线程同步问题
* 缺点:在类装载的时候完成了实例化,没有达到LZAY LOADING的效果,如果从始至终从未使用过这个实例,则会造成内存的浪费
* */
/*饿汉式(静态变量)*/
class Singleton{
// 1.构造器私有化,外部不能new
private Singleton(){
}
// 2.本类内部创建一个成员变量,用它来实例对象
private final static Singleton instance=new Singleton();
// 3.提供一个共有的静态方法得到实例对象
public static Singleton getInstance(){
return instance;
}
}
package singleton.type2;
/*所谓单例设计模式,就是采取一定的方法在整个软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得该对象实例的方法
* */
public class SingleTest02 {
public static void main(String[] args) {
/*饿汉式*/
Singleton instance = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance==instance2);
System.out.println(instance.hashCode());
System.out.println(instance2.hashCode());
}
}
/*优缺点分析
和上面的静态变量一模一样
* 优点:写法比较简单,就是在类装载的时候就完成了实例化。避免了线程同步问题
* 缺点:在类装载的时候完成了实例化,没有达到LZAY LOADING的效果,如果从始至终从未使用过这个实例,则会造成内存的浪费
* */
/*饿汉式(静态代码块)*/
class Singleton{
// 1.构造器私有化,外部不能new
private Singleton(){
}
// 2.本类内部创建一个成员变量,用它来实例对象
private static Singleton instance;
//在静态代码块中。创建单例对象
static {
// 这里直接instance代表上面的instance,否则空指针
instance=new Singleton();
}
// 3.提供一个共有的静态方法得到实例对象
public static Singleton getInstance(){
return instance;
}
}
package singleton.type3;
public class SingleTest03 {
public static void main(String[] args) {
/*饿汉式*/
singleton.type3.Singleton instance = singleton.type3.Singleton.getInstance();
singleton.type3.Singleton instance2 = singleton.type3.Singleton.getInstance();
System.out.println(instance==instance2);
System.out.println(instance.hashCode());
System.out.println(instance2.hashCode());
}
}
/*懒汉式*/
/*提供一个静态的共有方法。当使用到该方法时,才去创建instance*/
/*优缺点
优点:起到了懒加载的效果,但只能在单线程下使用
缺点:在多线程下,会产生多个实例
不推荐使用
* */
class Singleton{
private Singleton(){
}
private static Singleton instance;
public static Singleton getInstance(){
if(instance==null){
instance=new Singleton();
}
return instance;
}
} package singleton.type4;
public class SingleTest04 {
public static void main(String[] args) {
/*饿汉式*/
Singleton instance = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance==instance2);
System.out.println(instance.hashCode());
System.out.println(instance2.hashCode());
}
}
/*懒汉式*/
/*提供一个静态的共有方法。当使用到该方法时,才去创建instance*/
/*针对前面一种给出常识的改进*/
/*优缺点
优点:解决了线程不安全问题
缺点:效率太低了,只执行一次实例化代码就可以了,不需要每次进行同步,下一次就直接返回对象实例就可以了
不推荐使用
* */
class Singleton{
private Singleton(){
}
private static Singleton instance;
public static synchronized Singleton getInstance(){
if(instance==null){
instance=new Singleton();
}
return instance;
}
}
/*加在方法上 以及 加在判断语句里面 syschronized 都没有解决这个问题*/ package singleton.type5;
public class SingleTest05{
public static void main(String[] args) {
/*饿汉式*/
Singleton instance = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance==instance2);
System.out.println(instance.hashCode());
System.out.println(instance2.hashCode());
}
}
/*懒汉式*/
/*提供一个静态的共有方法。当使用到该方法时,才去创建instance*/
/*针对前面一种给出常识的改进*/
/*这种同步不同实现线程同步的作用,会产生多个实例*/
/*优缺点
优点:解决了线程不安全问题
缺点:效率太低了,只执行一次实例化代码就可以了,不需要每次进行同步,下一次就直接返回对象实例就可以了
不能使用
* */
class Singleton{
private Singleton(){
}
private static Singleton instance;
public static Singleton getInstance(){
if(instance==null){
synchronized(Singleton.class) {
instance = new Singleton();
}
}
return instance;
}
}
/*加在方法上 以及 加在判断语句里面 syschronized 都没有解决这个问题
* 前者效率低 后面线程不安全*/ package singleton.type6;
public class SingleTest06 {
public static void main(String[] args) {
/*饿汉式*/
Singleton instance = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance==instance2);
System.out.println(instance.hashCode());
System.out.println(instance2.hashCode());
}
}
/*懒汉式*/
/*提供一个静态的共有方法。当使用到该方法时,才去创建instance*/
/*针对前面一种给出常识的改进*/
/*双重检查
推荐使用 确保线程安全 延时加载 效率高
* */
class Singleton{
private Singleton(){
}
/*volatile的作用*/
private static volatile Singleton instance;
public static synchronized Singleton getInstance(){
if(instance==null){
synchronized (Singleton.class){
if(instance==null){
instance=new Singleton();
}
}
}
return instance;
}
}
/*加在方法上 以及 加在判断语句里面 syschronized 都没有解决这个问题*/ package singleton.type7;
public class SingleTest07 {
public static void main(String[] args) {
/*饿汉式*/
Singleton instance = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance==instance2);
System.out.println(instance.hashCode());
System.out.println(instance2.hashCode());
}
}
/*懒汉式*/
/*提供一个静态的共有方法。当使用到该方法时,才去创建instance*/
/*针对前面一种给出常识的改进*/
/*静态内部类 外部类被装载,内部类还没被装载 在调用方法时内部类会被装载而且装载一次,线程安全的
推荐使用 确保线程安全 延时加载 效率高
* */
class Singleton{
private Singleton(){
/*jvm在装载类的时候是线程安全的,利用了这个特性*/
}
private static volatile Singleton instance;
private static class SingletonInstance{
private static final Singleton INSTANCE = new Singleton();
}
/*提供一个静态的共有方法*/
public static synchronized Singleton getInstance(){
return SingletonInstance.INSTANCE;
}
}
package singleton.type8;
import org.w3c.dom.ls.LSOutput;
public class SingleTest08 {
public static void main(String[] args) {
//饿汉式
Singleton instance = Singleton.INSTANCE;
Singleton instance1 = Singleton.INSTANCE;
System.out.println(instance==instance1);
System.out.println(instance.hashCode());
System.out.println(instance1.hashCode());
instance.sayOK();
}
}
/*懒汉式*/
/*提供一个静态的共有方法。当使用到该方法时,才去创建instance*/
/*针对前面一种给出常识的改进*/
/*枚举.推荐使用,不仅能避免多线程同步问题,还可以防止反序列化重新创建新的对象
* */
enum Singleton{
INSTANCE;
public void sayOK(){
System.out.println("ok");
}
}
/*推荐饿汉式 枚举 静态内部类 懒汉式双重检查 一共5种方式
* 饿汉式你能确保一定使用*/
/*java.lang.Runtime就是经典的单例模式*/
/*单例模式保证了系统内存中该类只存在一个对象,节省了系统空间,对于一些需要频繁创建和销毁的对象,
使用单例模式可以提高系统性能
想实例化一个单例类的对象时,必须记住使用相应的获取该对象的方法,而不是使用new
单例模式使用的场景:需要频发的创建和销毁对象,但又要经常使用的对象。工具类对象,频繁使用数据库或者文件
的对象,比如数据源 session工厂等*/ 自己被加载时就将自己实例化,称为饿汉式单例类
第一次被引用时,才会将自己实例化,称为懒汉式单例类

京公网安备 11010502036488号