欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java多线程实战之单例模式与多线程的实例详解

程序员文章站 2024-02-29 12:57:16
1、立即加载/饿汉模式 // 立即加载/饿汉模式 public class myobject { private static final myobject...

1、立即加载/饿汉模式

// 立即加载/饿汉模式
public class myobject {
 private static final myobject myobject = new myobject();
 private myobject() {
 }
 public static myobject getinstance() {
 return myobject;
 }
}

立即加载/饿汉模式是在类创建的同时已经创建好一个静态的对象供系统使用,不存在线程安全问题

2、延迟加载/懒汉模式

// 延迟加载/懒汉模式
public class myobject {
 private static myobject myobject;
 private myobject() {
 }
 public static myobject getinstance() {
 if (myobject == null) {
  myobject = new myobject();
 }
 return myobject;
 }
}

延迟加载/懒汉模式是在调用方法时实例才被创建,在多线程环境下,会出现取出多个实例的情况,与单例模式的初衷是相背离的

1)、延迟加载/懒汉模式在多线程环境下创建出多个实例:

// 延迟加载/懒汉模式
public class myobject {
 private static myobject myobject;
 private myobject() {
 }
 public static myobject getinstance() {
 try {
  if (myobject == null) {
  timeunit.seconds.sleep(3);
  myobject = new myobject();
  }
 } catch (interruptedexception e) {
  e.printstacktrace();
 }
 return myobject;
 }
}
public class mythread extends thread {
 @override
 public void run() {
 system.out.println(myobject.getinstance().hashcode());
 }
}
public class run {
 public static void main(string[] args) {
 mythread mythread = new mythread();
 mythread mythread2 = new mythread();
 mythread mythread3 = new mythread();
 mythread.start();
 mythread2.start();
 mythread3.start();
 }
}

运行结果:三次打印的hashcode不完全相等

2)、通过声明synchronized关键字解决线程安全问题:

// 延迟加载/懒汉模式
public class myobject {
 private static myobject myobject;
 private myobject() {
 }
 public static synchronized myobject getinstance() {
 try {
  if (myobject == null) {
  timeunit.seconds.sleep(3);
  myobject = new myobject();
  }
 } catch (interruptedexception e) {
  e.printstacktrace();
 }
 return myobject;
 }
}

使用synchronized关键字,这种方法的运行效率很低,是同步运行的,下一个线程想要取得对象,则必须等上一个线程释放锁之后,才可以继续执行

3)、使用同步代码块解决线程安全问题:

// 延迟加载/懒汉模式
public class myobject {
 private static myobject myobject;
 private myobject() {
 }
 public static myobject getinstance() {
 try {
  // 相当于public static synchronized myobject getinstance()
  synchronized (myobject.class) {
  if (myobject == null) {
   timeunit.seconds.sleep(3);
   myobject = new myobject();
  }
  }
 } catch (interruptedexception e) {
  e.printstacktrace();
 }
 return myobject;
 }
}

加入同步代码块,这种方法的运行效率也是非常低,和synchronized同步方法一样是同步运行的

4)、针对某些重要的代码进行单独的同步

// 延迟加载/懒汉模式
public class myobject {
 private static myobject myobject;
 private myobject() {
 }
 public static myobject getinstance() {
 try {
  if (myobject == null) {
  timeunit.seconds.sleep(3);
  synchronized (myobject.class) {
   myobject = new myobject();
  }
  }
 } catch (interruptedexception e) {
  e.printstacktrace();
 }
 return myobject;
 }
}

此方法只对实例化对象的关键代码进行同步,从语句的结构上来讲,运行的效率的确得到了提升。但如果是多线程的情况下还是无法解决得到同一个实例对象的结果

5)、使用dcl双检查锁机制

// 延迟加载/懒汉模式
public class myobject {
 private volatile static myobject myobject;
 private myobject() {
 }
 public static myobject getinstance() {
 try {
  if (myobject == null) {
  timeunit.seconds.sleep(3);
  synchronized (myobject.class) {
   if (myobject == null) {
   myobject = new myobject();
   }
  }
  }
 } catch (interruptedexception e) {
  e.printstacktrace();
 }
 return myobject;
 }
}

使用dcl双检查锁机制,既保证了不需要同步代码的异步执行性,又保证了单例的效果

3、使用静态内部类实现单例模式

public class myobject {
 private static class myobjecthandler {
 private static myobject myobject = new myobject();
 }
 private myobject() {
 }
 public static myobject getinstance() {
 return myobjecthandler.myobject;
 }
}

4、使用静态代码块实现单例模式

public class myobject {
 private static myobject instance = null;
 private myobject() {
 }
 static {
 instance = new myobject();
 }
 public static myobject getinstance() {
 return instance;
 }
}

5、使用enum枚举实现单例模式

public class myobject {
 public enum myenumsingleton {
 objectfactory;
 private myobject myobject;
 private myenumsingleton() {
  myobject = new myobject();
 }
 public myobject getinstance() {
  return myobject;
 }
 }
 public static myobject getinstance() {
 return myenumsingleton.objectfactory.getinstance();
 }
}

枚举enum和静态代码块的特性相似,在使用枚举类时,构造方法会被自动调用,使用这个特性实现单例设计模式

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。如果你想了解更多相关内容请查看下面相关链接