单例模式概述
单例模式能解决什么问题呢?系统只需要一个实例对象,或者因为资源消耗太大而只允许创建一个对象。
在正常情况下只能打开唯一一个任务管理器!
当我们需要实例化窗口,希望满足窗口要么不出现,要么只出现一个,就需要用到单例模式。
单例模式定义:确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一实例。
在单例模式的定义中我们可以发现其三大要点:
单例模式的实现思路
一个类能够被创建多个实例,问题的根源在于类的构造方法是公开的,也就是可以让类的外部来通过构造方法创建多个实例。
要想控制一个类只被创建一个实例,那么首要的问题就是要把创建实例的权限收回来,让类自身来负责自己类实例的创建工作,然后由这个类来提供外部可以访问这个类实例的方法,这就是单例模式的实现方式。
两种类型的单例模式
3.1饿汉模式
public class Singleton {
private Singleton(){
}
//装载类的时候就创建对象实例
private static Singleton instance=new Singleton();
public static Singleton GetInstance(){
return instance;
}
}
3.2懒汉模式
public class Singleton {
private Singleton(){
}
private static Singleton instance=null;
public static Singleton GetInstance(){
//先判断实例是否存在,不存在再进行加锁处理
if(instance==null){
synchronized (Singleton.class) {//同一时刻只允许一个线程进入加锁的部分
if(instance==null){//第二重判断
instance=new Singleton();
}
}
}
return instance;
}
}
单例模式的实现代码
例子:
打印池
在操作系统中,打印池(Print Spooler)是一个用于管理打印任务的应用程序,通过打印池用户可以删除、中止或者改变打印任务的优先级,在一个系统中只允许运行一个打印池对象,如果重复创建打印池则抛出异常。现使用单例模式来模拟实现打印池的设计。
java代码实现:
打印任务类:
package com.study.singleton;
public class PrintTask {
private String name;
private int id;
private int priority;
private boolean print;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getPriority() {
return priority;
}
public void setPriority(int priority) {
this.priority = priority;
}
public boolean isPrint() {
return print;
}
public void setPrint(boolean print) {
this.print = print;
}
@Override
public String toString() {
return "任务id:"+id+",任务name:"+name+",任务优先级:"+priority+",任务是否在运行:"+print;
}
}
打印池类:
package com.study.singleton;
import java.util.ArrayList;
import java.util.List;
public class PrintPool {
private PrintPool() {}
private static PrintPool instance=null;
private List<PrintTask> printTaskList=new ArrayList<PrintTask>();
public static PrintPool getInstance(){
if(instance == null){
synchronized (PrintPool.class) {
if(instance == null){
instance=new PrintPool();
}
}
}
return instance;
}
public synchronized void deleteTask(int id){
for(int i= printTaskList.size()-1;i>=0;i--){
PrintTask printTask=printTaskList.get(i);
if(printTask.getId()==id){
System.out.println("删除成功"+printTask.toString());
printTaskList.remove(printTask);
break;
}
}
}
public synchronized void addTask(PrintTask printTask){
printTaskList.add(printTask);
System.out.println("添加成功"+printTask.toString());
}
public synchronized void changePriority(int id,int priority){
for(PrintTask pt:printTaskList){
if(pt.getId()==id){
pt.setPriority(priority);
System.out.println("改变优先级成功"+pt.toString());
break;
}
}
}
public synchronized void stopTask(int id){
for(PrintTask pt:printTaskList){
if(pt.getId()==id){
pt.setPrint(false);
System.out.println("停止任务"+pt.toString());
break;
}
}
}
}
测试类:
package com.study.singleton;
public class PrintClient {
public static void main(String[] args) {
Printtest ptest1 =new Printtest();
Printtest ptest2=new Printtest();
Thread t1 = new Thread(ptest1);
Thread t2 = new Thread(ptest2);
t1.start();
t2.start();
PrintTask p1=new PrintTask();
p1.setId(1);
p1.setName("任务1");
p1.setPrint(true);
p1.setPriority(1);
PrintTask p2=new PrintTask();
p2.setId(2);
p2.setName("任务2");
p2.setPrint(true);
p2.setPriority(2);
PrintPool.getInstance().addTask(p1);
PrintPool.getInstance().addTask(p2);
PrintPool.getInstance().changePriority(2, 5);
PrintPool.getInstance().stopTask(1);
PrintPool.getInstance().deleteTask(2);
}
public static class Printtest implements Runnable {
public void run() {
try {
System.out.println(PrintPool.getInstance().hashCode());
} catch (Exception e) {
}
}
}
}
结果: