单例模式
单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制,并节约系统资源。如果希望在系统中某个类对象只能存在一个单例模式是最好的解决方案。
单例模式分为懒汉式和饿汉式
懒汉式和饿汉式的区别:
饿汉式不管有没有调用getInstance()方法,都会在系统中创建一个静态对象
饿汉式优点:在多线程模式下是安全的
缺点:没有调用方法前就被加载,会占用内存
懒汉式不会预先创建对象,只有在第一次使用时创建
懒汉式优点:只有调用方法才创建对象,不会占用内存、
缺点:在多线程模式下不安全
线程安全
- 饿汉式本身就是线程安全的,可以直接用于多线程而不会出现问题
- 懒汉式是非线程安全的,解决方式如下:
关键字:synchronized:可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这个段代码
代码锁
package com.jredu.oop.ch0502;
/**
* 静态内部类实现方式
* 单例模式类
* @author Administrator
*/
public class Singleton4 {
/**
* 私有化构造
*/
private Singleton4() {
System.out.println("对象创建成功");
}
static int a=10;
/**
* static关键字修饰的内容,只会加载一遍
*/
static {
// a=10;
// getInstance();
System.out.println("类被加载");
// Singleton4Handler.instance;
}
/**
* static除了修饰内部类以外,
* 其他情况都是只要类被加载之后就会执行static代码,
* 静态内部类只有被调用时才会加载
* @author Administrator
*
*/
public static class Singleton4Handler{
static{
System.out.println("内部类被加载");
}
static Singleton4 instance=new Singleton4();
}
public static Singleton4 getInstance() {
return Singleton4Handler.instance;
}
public static void main(String[] args) {
//多线程操作
//2.直接使用Thread操作
Thread thread1=new Thread(){
@Override
public void run() {
// TODO Auto-generated method stub
//
Singleton4 ton=Singleton4.getInstance();
System.out.println(ton.hashCode());
}
};
thread1.start();
// Thread thread2=new Thread(){
// @Override
// public void run() {
// // TODO Auto-generated method stub
// Singleton4 ton2=Singleton4.getInstance();
// System.out.println(ton2.hashCode());
// }
// };
// //开启新线程
// thread2.start();
Ch02 ch02=new Ch02();
ch02.test();
}
}
懒汉式单例模式
package com.jredu.oop.ch0502;
/**
* 懒汉式
* 单例模式类
* @author Administrator
*/
public class Singleton3 {
/**
* 私有化构造
*/
private Singleton3() {
System.out.println("对象创建成功");
}
//全局对象
private static Singleton3 singleton=null;
public static Singleton3 getInstance() {
//判断全局对象是否为空
if(singleton==null) {
//休眠一秒钟
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//线程锁
synchronized (Singleton3.class) {
if(singleton==null) {
//如果为空,就创建该类对象
singleton=new Singleton3();
}
}
}
//如果不为空,就直接返回该对象
return singleton;
}
public static void main(String[] args) {
//多线程操作
//2.直接使用Thread操作
Thread thread1=new Thread(){
@Override
public void run() {
// TODO Auto-generated method stub
//
Singleton3 ton=Singleton3.getInstance();
System.out.println(ton.hashCode());
}
};
thread1.start();
Thread thread2=new Thread(){
@Override
public void run() {
// TODO Auto-generated method stub
Singleton3 ton2=Singleton3.getInstance();
System.out.println(ton2.hashCode());
}
};
//开启新线程
thread2.start();
// Ch02 ch02=new Ch02();
// ch02.test();
}
}