1.情景,只有一个仓库,搬运员工同时在这仓库工作。
class StoreHouse
{
private int quantity=100;
public void SetQuantity(int quantity)
{
this.quantity = quantity;
}
public int GetQuantity()
{
return quantity;
}
}
class Carrier
{
private StoreHouse storeHouse;
public Carrier(StoreHouse storeHouse)
{
this.storeHouse = storeHouse;
}
public void Out(int number)
{
storeHouse.SetQuantity(storeHouse.GetQuantity() - number);
}
public void In(int number)
{
storeHouse.SetQuantity(storeHouse.GetQuantity() + number);
}
}
class Program
{
static void Main(string[] args)
{
StoreHouse storeHouseA= new StoreHouse();
StoreHouse storeHouseB = new StoreHouse();
Console.WriteLine("是同一个吗?");
if(storeHouseA==storeHouseB)
{
Console.WriteLine("是的");
}
else
{
Console.WriteLine("不是的");
}
Carrier carrierA = new Carrier(storeHouseA);
Carrier CarrierB = new Carrier(storeHouseB);
carrierA.In(100);
CarrierB.Out(100);
Console.WriteLine(storeHouseA.GetQuantity());
Console.WriteLine(storeHouseB.GetQuantity());
}
}
结果:
代码运行没错,但是不是我们想要的,我们想要的输出是同一家仓库,输出结果100和100,即我们搬运工操作的是同一个仓库,这是可以用单例给我们解决问题了。
1.饿汉式
using System;
namespace Singleton
{
class StoreHouse
{
private int quantity=100;
private static StoreHouse storeHouse=new StoreHouse();
private StoreHouse()
{
}
public static StoreHouse GetInstance()
{
return storeHouse;
}
public void SetQuantity(int quantity)
{
this.quantity = quantity;
}
public int GetQuantity()
{
return quantity;
}
}
class Carrier
{
private StoreHouse storeHouse;
public Carrier(StoreHouse storeHouse)
{
this.storeHouse = storeHouse;
}
public void Out(int number)
{
storeHouse.SetQuantity(storeHouse.GetQuantity() - number);
}
public void In(int number)
{
storeHouse.SetQuantity(storeHouse.GetQuantity() + number);
}
}
class Program
{
static void Main(string[] args)
{
StoreHouse storeHouseA= StoreHouse.GetInstance();
StoreHouse storeHouseB = StoreHouse.GetInstance();
Console.WriteLine("是同一个吗?");
if(storeHouseA==storeHouseB)
{
Console.WriteLine("是的");
}
else
{
Console.WriteLine("不是的");
}
Carrier carrierA = new Carrier(storeHouseA);
Carrier CarrierB = new Carrier(storeHouseB);
carrierA.In(100);
CarrierB.Out(100);
Console.WriteLine(storeHouseA.GetQuantity());
Console.WriteLine(storeHouseB.GetQuantity());
}
}
}
运行结果:
是同一个吗?
是的
100
100
优点:线程安全,永远只有一个实例。
缺点:用户无法控制什么时候生成实例,类加载的时候实例。
2.懒汉式
//懒汉式
class StoreHouse
{
private int quantity = 100;
private static StoreHouse storeHouse =null;
private StoreHouse()
{
}
public static StoreHouse GetInstance()
{
ifc
storeHouse =new StoreHouse();
return storeHouse;
}
public void SetQuantity(int quantity)
{
this.quantity = quantity;
}
public int GetQuantity()
{
return quantity;
}
}
优点:在需要的地方在创建,如这次是在StoreHouse.GetInstance()实例,而饿汉式是在类加载的时候实例。
缺点:不是线程安全的,可能会创建多个storeHouse,比说线程A已经运行到了storeHouse =new StoreHouse();但还没有生成实例,B运行到if (storeHouse == null)时成立,积雪运行到storeHouse =new StoreHouse(),那么A,B线程都各自生成了一个实例,这不是我们想要的。为了解决这问题我们引入了同步。
class StoreHouse
{
private int quantity = 100;
private static StoreHouse storeHouse = null;
private StoreHouse()
{
}
public static StoreHouse GetInstance()
{ lock(storeHouse)
{
if (storeHouse == null)
storeHouse = new StoreHouse();
return storeHouse;
}
}
public void SetQuantity(int quantity)
{
this.quantity = quantity;
}
public int GetQuantity()
{
return quantity;
}
}
虽然解决了线程安全问题,但是每次都要调用lock,开销增大。于是有了下面的改进版
public static StoreHouse GetInstance()
{ if(storeHouse==null)
{
lock (storeHouse)
{
if (storeHouse == null)
storeHouse = new StoreHouse();
}
}
return storeHouse;
}