单例模式——读取配置文件到内存
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class main {
public static void main(String[] args) {
AppConfig config = new AppConfig();
String paramA = config.getParameterA();
String paramB = config.getParameterB();
System.out.println("paramA=" + paramA + ",paramB=" + paramB);
}
}
class AppConfig {
private String parameterA;
private String parameterB;
public String getParameterA() {
return parameterB;
}
public String getParameterB() {
return parameterB;
}
public AppConfig() {
readConfig();
}
private void readConfig() {
Properties p = new Properties();
InputStream in = null;
try {
in = AppConfig.class.getResourceAsStream("AppConfig.properties");
p.load(in);// 获取资源文件的输入流,从输入流中读取属性列表
this.parameterA = p.getProperty("paramA");
this.parameterB = p.getProperty("paramB");
} catch (IOException e) {
System.out.println("装载配置文件出错");
e.printStackTrace();
} finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点
- 单例模式的特点:
- 单例类只能有一个实例
- 单例类必须自己创建自己的唯一实例
- 单例类必须给所有其他对象提供这一实例
public class main {
public static void main(String[] args) {
// Singleton s0=new Singleton();
Singleton s1 = Singleton.GetInstance();
Singleton s2 = Singleton.GetInstance();
if (s1 == s2) {
System.out.println("两个对象是相同的实例");
} else {
System.out.println("两个对象是不同的实例");
}
}
}
//单例类
class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton GetInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
多线程时的单例
public class main {
public static void main(String[] args) {
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
if (s1 == s2) {
System.out.println("该对象的字符串表示形式:");
System.out.println("singleton1:"+s1.toString());
System.out.println("singleton2:"+s2.toString());
}
}
}
class Singleton {
private static Singleton instance;
private static final Object syncRoot = new Object();// 程序运行时创建一个静态只读的进程辅助对象
public static Singleton getInstance() {
synchronized (syncRoot) {//在同一时刻加了锁的部分程序只有一个线程可以进入
if (instance == null) {
instance = new Singleton();
}
}
System.out.println("singleton创建");
return instance;
}
}
- 这里不直接synchronized(instance),而是再创建一个syncRoot来synchronized的原因:
- 在加锁时,instance不一定被创建过,无法对它加锁。
双重锁定: 不用让线程每次都加锁,而只是在实例未被创建的时候加锁。
public class main {
public static void main(String[] args) {
SingletonDCL s1=SingletonDCL.getInstance();
SingletonDCL s2=SingletonDCL.getInstance();
System.out.println("s1==s2?"+(s1==s2));
System.out.println("该对象的字符串表示形式:");
System.out.println("singleton1:"+s1.toString());
System.out.println("singleton2:"+s2.toString());
}
}
class SingletonDCL{
private volatile static SingletonDCL singleton;
private SingletonDCL() {}
public static SingletonDCL getInstance() {//此方法是获得本类实例的唯一全局访问点
if(singleton==null) {//给类加锁,类的所有对象用同一把锁
synchronized(SingletonDCL.class) {
if(singleton==null) {
singleton=new SingletonDCL();
}
}
}
System.out.println("singleton创建");
return singleton;
}
}
单例模式的实现分为两种:
懒汉式单例模式(时间换空间)
:在第一次被引用时才会将自己实例化。
class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton GetInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
饿汉式单例模式(空间换时间)
:只能在静态初始化期间或在类构造函数中分配变量,
这种静态初始化的方式是在自己被加载时就将自己实例化。
class Singleton{
private static Singleton instance=new Singleton();
private Singleton(){}
public static Singleton GetInstance() {
return instance;
}
}
二者主要区别:
-
懒汉式会面临这多线程访问的安全性问题,需要做双重锁定处理才可以保证安全。
-
饿汉式即静态初始化的方式,它是类一加载就实例化的对象,所以要提前占用系统资源。**
享元模式——实现不同客户对同一网站的不同需求
将对象的状态按照是否会变化分为不同的状态,共享不变的状态
//客户端代码
public class main {
public static void main(String[] args) {
WebSite fx=new WebSite("产品展示");
fx.Use();
WebSite fy=new WebSite("产品展示");
fy.Use();
WebSite fz=new WebSite("产品展示");
fz.Use();
WebSite fl=new WebSite("博客");
fl.Use();
WebSite fm=new WebSite("博客");
fm.Use();
WebSite fn=new WebSite("博客");
fn.Use();
}
}
//网站类
class WebSite{
private String name="";
public WebSite(String name) {
this.name=name;
}
public void Use() {
System.out.println("网站分类:"+name);
}
}
上面的代码有资源浪费问题
解决方法:
利用用户的ID号来区分不同的用户,各个小网站的具体数据和模板乐意不同,但核心代码却是共享的。
public class main {
public static void main(String[] args) {
int extrinsic=22;
FlyweightFactory f=new FlyweightFactory();
Flyweight fx=f.getFlyweight("X");
fx.operate(--extrinsic);
Flyweight fy=f.getFlyweight("Y");
fy.operate(--extrinsic);
Flyweight fz=f.getFlyweight("Z");
fz.operate(--extrinsic);
Flyweight fex=f.getFlyweight("X");
fex.operate(--extrinsic);
Flyweight unsharedFlyweight=new UnsharedConcreteFlyweight("X");
unsharedFlyweight.operate(--extrinsic);
}
}
/*享元类是所有具体享元类的超类或接口,通过这个接口,享元类可以接受并作用域外部状态。*/
abstract class Flyweight{
public String intrinsic;//内部状态
protected final String extrinsic;//外部状态
public Flyweight(String extrinsic) {
this.extrinsic=extrinsic;
}
public abstract void operate(int intrinsic) ;//定义业务操作
public String getIntrinsic() {
return intrinsic;
}
public void setIntrinsic(String intrinsic){
this.intrinsic=intrinsic;
}
}
class ConcreteFlyweight extends Flyweight{
public ConcreteFlyweight(String extrinsic) {
super(extrinsic);
}
public void operate(int extrinsic) {
System.out.println("具体的Flyweight:"+extrinsic);
}
}
class UnsharedConcreteFlyweight extends Flyweight{
public UnsharedConcreteFlyweight(String extrinsic) {
super(extrinsic);
}
public void operate(int extrinsic) {
System.out.println("不共享的具体的Flyweight:"+extrinsic);
}
}
//享元工厂
class FlyweightFactory{
private static HashMap<String,Flyweight>pool=new HashMap<String,Flyweight>();
public static Flyweight getFlyweight(String extrinsic) {
Flyweight flyweight=null;
if(pool.containsKey(extrinsic)) {//池中有对象
flyweight=pool.get(extrinsic);
System.out.print("创建"+extrinsic+"并从池中取出");
}else {
flyweight=new ConcreteFlyweight(extrinsic);
pool.put(extrinsic, flyweight);//放入池中
System.out.print("创建"+extrinsic+"并从池中取出");
}
return flyweight;
}
}
public class main {
public static void main(String[] args) {
WebSiteFactory f=new WebSiteFactory();
WebSite fx=f.GetWebSiteCategory("产品展示");
fx.Use();
WebSite fy=f.GetWebSiteCategory("产品展示");
fy.Use();
WebSite fz=f.GetWebSiteCategory("产品展示");
fz.Use();
WebSite fl=f.GetWebSiteCategory("博客");
fl.Use();
WebSite fm=f.GetWebSiteCategory("博客");
fm.Use();
WebSite fn=f.GetWebSiteCategory("博客");
fn.Use();
}
}
abstract class WebSite{
public abstract void Use();
}
class ConcreteWebSite extends WebSite{
private String name="";
public ConcreteWebSite(String name) {
this.name=name;
}
public void Use() {
System.out.println("网站分类:"+name);
}
}
//网站工厂
class WebSiteFactory{
private static HashMap<String,WebSite>flyweights=new HashMap<String,WebSite>();//获得网站分类
public WebSite GetWebSiteCategory(String key) {
if(!flyweights.containsKey(key)) {
WebSite flyweight=new ConcreteWebSite(key);
flyweights.put(key, flyweight);
}
return (flyweights.get(key));
}
public int GetWebSiteCount() {//获得网站分类总数
return flyweights.size();
}
}
public class main {
public static void main(String[] args) {
WebSiteFactory f=new WebSiteFactory();
WebSite fx=f.GetWebSiteCategory("产品展示");
fx.Use(new User("小草"));
WebSite fy=f.GetWebSiteCategory("产品展示");
fy.Use(new User("大鸟"));
WebSite fz=f.GetWebSiteCategory("产品展示");
fz.Use(new User("小花"));
}
}
//网站抽象类
abstract class WebSite{
public abstract void Use(User user);
}
class User{
private String name;
User(String name){
this.name=name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name=name;
}
}
class ConcreteWebSite extends WebSite{
private String name="";
public ConcreteWebSite(String name) {
this.name=name;
}
public void Use(User user) {
System.out.println("网站分类:"+name+"用户:"+user.getName());
}
}
class WebSiteFactory{
private static HashMap<String,WebSite>flyweights=new HashMap<String,WebSite>();//获得网站分类
public WebSite GetWebSiteCategory(String key) {
if(!flyweights.containsKey(key)) {
WebSite flyweight=new ConcreteWebSite(key);
flyweights.put(key, flyweight);
}
return (flyweights.get(key));
}
public int GetWebSiteCount() {//获得网站分类总数
return flyweights.size();
}
}
版权声明:本文为weixin_43470016原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。