单例模式
单例模式,一个单一的类,构造器私有,提供自身创建的方法,实例对象,在内部生成,并且在程序整个生命周期有且仅有一个实例。属于创建型模式。
单例模式的目的
保证一个类有且仅有一个实例,并提供一个全局访问点。避免了全局类的频繁创建或销毁,提高程序运行效率。
什么时候会使用到单例模式
当你想控制系统的实例数目,节省系统资源时可以用到。如程序计数器,生成唯一序列号,非常消耗资源的对象,如I/O操作和数据库连接。
单例模式实行方式
饿汉模式(线程安全)
public class HungrySingleton {
private final static HungrySingleton hungrySingleton= new HungrySingleton();
private HungrySingleton() {}
public static HungrySingleton getInstance(){
return hungrySingleton;
}
public void showType(){
System.out.println("我是饿汉单例模式");
}
}
懒汉模式(非线程安全)
public class LazySingleton {
private static LazySingleton lazySingleton = null;
private LazySingleton(){}
public LazySingleton getInstance(){
if(lazySingleton == null)
lazySingleton = new LazySingleton();
return lazySingleton;
}
public void showType(){
System.out.println("我是懒汉且不是线程安全的单例模式");
}
}
懒汉模式 (线程安全) 网站登录计数器为例子
public interface WebCounter {
void oneOnline();
void oneOffline();
int getOnlineNum();
}
###############
public class ThreadSecurityLazySingleton implements WebCounter{
int online = 0;
//保证多线程实例同步
private static volatile ThreadSecurityLazySingleton threadSecurityLazySingleton = null;
//避免外部实例化
private ThreadSecurityLazySingleton() { }
//方法前加上 同步关键字,保证线程安全
public static synchronized ThreadSecurityLazySingleton getInstance(){
if(threadSecurityLazySingleton == null){
threadSecurityLazySingleton = new ThreadSecurityLazySingleton();
}
return threadSecurityLazySingleton;
}
@Override
public synchronized void oneOnline() {
online = online+1;
}
@Override
public void oneOffline() {
--online;
}
@Override
public int getOnlineNum() {
return online;
}
}
###############
public class Main {
public static void main(String[] args){
ThreadSecurityLazySingleton threadSecurityLazySingleton = ThreadSecurityLazySingleton.getInstance();
for (int i = 1;i <= 10;i++){
new Thread(new WebMan(),"线程 "+i).start();
}
}
}
class WebMan implements Runnable{
ThreadSecurityLazySingleton threadSecurityLazySingleton = ThreadSecurityLazySingleton.getInstance();
@Override
public void run() {
System.out.println("线程:"+Thread.currentThread().getName()+" 登录了");
threadSecurityLazySingleton.oneOnline();
System.out.println("当前登录人数:"+threadSecurityLazySingleton.getOnlineNum());
}
}