设计模式之单例模式c,设计模式之单例模式代码
单例模式:确保一个类只有一个实例,并提供一个全局访问点。
在单例模式下,当需要返回单个实例时,唯一的方法是通过单例类获取它。
案例代码下载
情景:小明家只有一辆车。在某一时刻,汽车只有一种状态,要么前进,要么后退,就是倒车。
案例代码:
在正式的单例模式中,单例类需要通过一个通用的全局访问点提供一个类似的构造方法。在这个测试代码中,singleton模式稍微做了一些改变,以比较不同之处。
在单例模式中只允许创建一个对象。为了检查它是否是一个对象,我打印出了对象的hashCode。
1、Test.java
公共类测试{
公共静态void main(String args[]){
//小明家只有一辆车。
//一个类可以有许多实例。
汽车c_a=新车();
汽车c_b=新车();
c _ a . driverbackward();
c _ b . driver forward();
system . out . println(c _ a);//Car [mName=小明的车,mState=倒车]hashCode373882728
system . out . println(c _ b);//Car [mName=小明的车,mState=向前行驶]hashCode309858374
system . out . println(-);
//使用单例模式管理汽车
//虽然创建了两个对象,但同时只有一个引用。
car c _ 1=singletonnumone . getinstance();
car c _ 2=singletonnumone . getinstance();
c _ 1 . driverbackward();
system . out . println(c _ 1);//Car [mName=小明的车,mState=倒车]hashCode241990244
system . out . println(c _ 2);//Car [mName=小明的车,mState=倒车]hashCode241990244
system . out . println(-);
c _ 2 . driver forward();
system . out . println(c _ 1);//Car [mName=小明的车,mState=向前行驶]hashCode241990244
system . out . println(c _ 2);//Car [mName=小明的车,mState=向前行驶]hashCode241990244
2.SingletonNumOne.java//单例对象获取类
这种模式被称为“延迟实例化”模式,它创建单例对象。这种模式在大多数状态下正常工作,但在多线程系统中就不那么正常了。
3、TestMultiThread.java
公共类test多线程{
公共静态void main(String args[]){
new thread n1=new new thread();
new thread N2=new new thread();
新线程(n1)。start();
新线程(n2)。start();
尝试{
thread . sleep(3000);
} catch (InterruptedException e) {
//TODO自动生成的catch块
e . printstacktrace();
car C1=n1 . getcar();
car C2=N2 . getcar();
system . out . println(C1);//Car [mName=小明的车,mState=null]hashCode1667685889
system . out . println(C2);//Car [mName=小明的车,mState=null]hashCode1987659426
类NewThread实现Runnable{
car car _ 1;
@覆盖
公共无效运行(){
car _ 1=singletonnumone . getinstance();
公共汽车getCar(){
还车_ 1;
因此,我将输出附加到打印函数上。通过hashcode,我们可以看到这是两个不同的对象。你不是说通过singleton模式得到了同样的对象吗?这是怎么回事?
其实这是java同步和并发造成的。想象多个线程同时运行SingletonNumOne.getInstance()方法。每个线程都可能得到时间片,并在任何时刻执行这个函数,这将导致。一个线程在实例化新车,另一个线程在这里运行。
这个问题有三个解决方案。
第一种解决方案:添加同步锁。
4、SingletonNumOne.java
公共类SingletonNumOne {
私人静态车car=null
公共静态同步汽车getInstance(){
if(car==null){
尝试{
线程.睡眠(2000年);
} catch (InterruptedException e) {
//TODO自动生成的catch块
e . printstacktrace();
汽车=新车();
还车;
第二种方式:使用“热切创建模式”来获取单例对象。
5、SingletonNumTwo.java
公共类SingletonNumTwo {
私人静态车car=新车();
公共静态同步汽车getInstance(){
还车;
第三种方式:双重检查并锁定。
6、SingletonNumThree.java
公共类SingletonNumThree {
私人挥发性静态汽车mCar
公共静态汽车getInstance(){
if(mCar==null){
同步(Car.class){
if(mCar==null){
mCar=新车();
返回mCar
附上
每次线程访问可变修饰成员变量时,都会强制从共享内存中重新读取成员变量的值。此外,当成员变量改变时,线程被迫将改变后的值写回共享内存。这样,在任何时候,两个不同的线程总是看到同一个成员变量的值。
测试类别:
7、Test2.java
公共类Test2 {
公共静态void main(String args[]){
//第一个方法SingletonNumOne为getInstance方法添加同步锁。
car car 1=singletonnumone . getinstance();
car car 2=singletonnumone . getinstance();
system . out . println(car 1);//Car [mName=小明的车,mState=null]hashCode613481760
system . out . println(car 2);//Car [mName=小明的车,mState=null]hashCode613481760
system . out . println(-);
//第二个方法是singleton模式的“热切”创建方法。
car car 3=singletonnumtwo . getinstance();
car car 4=singletonnumtwo . getinstance();
system . out . println(car 3);//Car [mName=小明的车,mState=null]hashCode1987659426
system . out . println(car 4);//Car [mName=小明的车,mState=null]hashCode1987659426
system . out . println(-);
//第三种方法://双重检查锁定
car car 5=singletonnumthree . getinstance();
car car 6=singletonnumthree . getinstance();
system . out . println(car 5);//Car [mName=小明的车,mState=null]hashCode2048243029
system . out . println(car 6);//Car [mName=小明的车,mState=null]hashCode2048243029
我将测试结果附加到打印功能中。
总结:singleton模式保证了一个程序中的一个类只有一个实例对象,singleton模式为访问这个singleton对象提供了一个全局访问点。在java中实现singleton模式,需要有一个构造函数,一个静态方法和一个静态变量。使用单片式模式的第一种方案时,要处理多线程带来的问题。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。