标签:懒汉式 产生 img 设计 数据 class static 单线程 hash
单例即只有一个实例,该模式的作用是保证程序中某个类的对象只有一个。
单例模式分为懒汉式和饿汉式。
class Student{
static Student st;
private Student(){}
public static Student getInstance(){
//引用数据类型属性在内存中的默认值为null
//如果值为null 只创建一次对象
if(st==null){
st = new Student();
}
return st;
}
}
public class Test1 {
public static void main(String[] args) {
// 利用hascode 相等 是单例
Student tes1 = Student.getInstance();
System.out.println(tes1.hashCode());
Student tes2 = Student.getInstance();
System.out.println(tes2.hashCode());
}
}
以上可以看出结果的hasCode值是相同的只创建了一个对象

但是这种模式在多线程的情况下会产生线程安全问题:
class Teacher{
static Teacher s;
private Teacher(){}
public static Teacher getInstance(){
if(s == null){
s = new Teacher();
}
return s;
}
}
class StudentThread extends Thread{
public void run(){
for(int i = 0;i<3;i++){
Teacher ss = Teacher.getInstance();
System.out.println(ss.hashCode());
}
}
}
public class Test2 {
public static void main(String[] args) {
//单例模式在多线程中存在线程安全问题 需要解决线程安全
//创建线程
StudentThread tt1 = new StudentThread();
StudentThread tt2 = new StudentThread();
//就绪状态
tt1.start();
tt2.start();
}
}
如果在运行多次的情况下会出现hasCode不一定都一样 这就出现了线程安全问题:

解决办法只需要将返回对象的方法设置为同步方法即可
public synchronized static Teacher getInstance(){
if(s == null){
s = new Teacher();
}
return s;
}
//饿汉式
class Hangle{
//创建静态属性的时候就赋值 并且只执行一次 也就是说只创建一次对象
static Hangle ha = new Hangle();
public static Hangle getInstance(){
return ha;
}
}
class SingleThread extends Thread{
public void run(){
for(int i = 0;i<4;i++){
Hangle hh = Hangle.ha;
System.out.println(hh.hashCode());
}
}
}
public class Test3 {
public static void main(String[] args) {
SingleThread tt1 = new SingleThread();
SingleThread tt2 = new SingleThread();
//就绪状态
tt1.start();
tt2.start();
// 总结: 懒汉式 在多线程环境中会发生线程安全问题 (可以解决线程问题)
//而饿汉式不管是在单线程还是在多线程中 不存在线程安全问题 建议定义单例模式的话 用饿汉式
//饿汉式单例模式要比懒汉式效率高
}
}
标签:懒汉式 产生 img 设计 数据 class static 单线程 hash
原文地址:https://www.cnblogs.com/nianzhilian/p/9108589.html