首页 > 后端开发 > 正文

如何写一个标准的Java单例模式

2024-04-05 13:39:52 | 我爱编程网

如何写一个标准的Java单例模式很多朋友对这方面很关心,我爱编程网整理了相关文章,供大家参考,一起来看一下吧!

本文目录一览:

如何写一个标准的Java单例模式

让Java程序只运行一个实例

一个程序可以在内存里面存在多个运行实例 比如 你可以打开多个微软的Word程序 但是 有些时候我们需要控制程序运行的实例只有一个 也就是说 该程序同一时刻在内存里面运行的只有一个实例 这样当这个程序在内存中已经存在一个运行实例而用户又再次运行了该程序的时候 有两种结果 第一种结果是结束目前的运行实例 打开新运行的实例 第二种就是让新运行的实例退出 原有的运行实例继续运行      原理   因为任何时候只有一个实例 所以在实现这种功能的时候必须借助只能被独享的资源 如果我们的程序是基于某个平台的 那么就可以借助操作系统的内核对象来完成 比如Windows操作系统就提供了CreateMutex这个API来创建一个独享的内核对象 但是因为要考虑平台无关 Java程序的实例控制不应该使用系统的内核对象来完成 那么我们就必须找到其它的 可以独享的资源 实际上 一台机器无论是在什么操作系统上 网络端口都是独享的 也就是说基于网络端口这个独享的原理 我们可以很方便地让我们的Java程序实现在内存里面只有一个运行实例这个功能 而且这个功能的实现是与平台无关的      实现   我们先来看看第一种情况是如何实现的 也就是说如果系统中已经存在运行实例的话 那么结束原有的运行实例 让新实例运行 这个实现实例控制的Java类也是一个线程 具体的实现如下     import *;  public class InstanceControl extends Thread {   public void run() {   try{    Socket sock = new Socket( );   //创建socket 连接 端口                      }   catch (Exception e)   {}   try{    ServerSocket server = new ServerSocket( );//创建socket 在 端口监听    server accept(); //等待连接    server close(); //有连接到来 也就是说有新的实例    System exit( ); //这个实例退出   }catch (Exception e)   {    e printStackTrace();   }   }  }     下面这个Java程序的程序入口是没有实例控制功能的     public class ProgramMain {   public static void main(String argv[])   {   mainFrame frame = new mainFrame();   }  }     现在想加入实例控制 只需要添加两行代码 添加后代码如下所示     public class ProgramMain {   public static void main(String argv[])   {   InstanceControl ic = new InstanceControl();   ic start();   mainFrame frame = new mainFrame();   }  }     在这个基础上 要实现第二种情况 也就是已经有实例运行的情况下 新的实例退出 保持原有的运行实例 就只需要一点小的改动了 具体的实现如下     import *;  public class InstanceControl extends Thread {   public void run() {   try{    Socket sock = new Socket( );//创建socket 连接 端口    System exit( ); //连接成功 说明有实例存在 则退出   }catch (Exception e)   {}   try{    ServerSocket server = new ServerSocket( );//创建socket 连接 端口    while (true)    {    server accept(); //接受连接请求    }   }catch (Exception e)   {    e printStackTrace();   }   }  }     这个类的使用方法和第一种情况的那个类是一样的 只需要在原有的代码上加入两行代码即可     InstanceControl ic = new InstanceControl();  ic start();     扩展   上面的程序也许有一个小bug 就是如果程序在开始运行时ServerSocket监听的端口已经被其它程序占用 那么程序的运行就会受到影响 所以程序的端口应该尽量取得大一些 在这种情况下其它程序占用这个程序使用的端口的概率是可以忽略不计的 同时 还可以做两种扩展 第一种是把端口写在配置文件中 可通过读配置文件得到端口 这样就能够在其它程序占用目前端口的情况下改变这个程序使用的端口 还有一种是在运行的时候用两个InstanceControl类分别在两个端口监听 只要有一个InstanceControl类得到连接就做出响应 这样两个端口都被其它程序占用的概率就更加的微乎其微了 lishixinzhi/Article/program/Java/Javascript/201311/25374

如何写一个标准的Java单例模式

如何写一个标准的Java单例模式

java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。

单例模式有一下特点:

1、单例类只能有一个实例。

2、单例类必须自己自己创建自己的唯一实例。

3、单例类必须给所有其他对象提供这一实例。

单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态,避免政出多头。

首先看一个经典的单例实现。

public class Singleton {

private static Singleton uniqueInstance = null;

private Singleton() {

// Exists only to defeat instantiation.

}

public static Singleton getInstance() {

if (uniqueInstance == null) {

uniqueInstance = new Singleton();

}

return uniqueInstance;

}

// Other methods...

}

Singleton通过将构造方法限定为private避免了类在外部被实例化,在同一个虚拟机范围内,Singleton的唯一实例只能通过getInstance()方法访问。(事实上,通过Java反射机制是能够实例化构造方法为private的类的,那基本上会使所有的Java单例实现失效。此问题在此处不做讨论,姑且掩耳盗铃地认为反射机制不存在。)

但是以上实现没有考虑线程安全问题。所谓线程安全是指:如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。显然以上实现并不满足线程安全的要求,在并发环境下很可能出现多个Singleton实例。

//////////////////////////////////////////////////////////////////////

验证单例模式的示例

//////////////////////////////////////////////////////////////////////

public class TestStream {

private String name;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

// 该类只能有一个实例

private TestStream() {

} // 私有无参构造方法

// 该类必须自行创建

// 有2种方式

private static TestStream ts1 = null;

// 这个类必须自动向整个系统提供这个实例对象

public static TestStream getTest() {

if (ts1 == null) {

ts1 = new TestStream();

}

return ts1;

}

public void getInfo() {

System.out.println("output message " + name);

}

public static void main(String[] args) {

TestStream s = TestStream.getTest();

s.setName("张孝祥 1");

System.out.println(s.getName());

TestStream s1 = TestStream.getTest();

s1.setName("张孝祥 2");

System.out.println(s1.getName());

s.getInfo();

s1.getInfo();

if (s == s1) {

System.out.println("创建的是同一个实例");

} else if (s != s1) {

System.out.println("创建的不是同一个实例");

} else {

System.out.println("application error");

}

}

}

////////////////////////////////////////////我爱编程网

如何写一个标准的Java单例模式

java中哪些对象都是单例模式

下面列出一部分Java的单例类:

1)Runtime类

可以通过java.lang.Runtime#getRuntime()获取其实例

2)Desktop类

可以通过java.awt.Desktop#getDesktop()获取其实例

3)SecurityManager类,注意,虽然该类提供了公共无参构造函数,但其内部构造函数仍然以单例的模式在运行。可以说是单例的一种变形设计。

可以通过java.lang.System#getSecurityManager()获取其实例

以上就是我爱编程网为大家带来的如何写一个标准的Java单例模式,希望能帮助到大家!
与“如何写一个标准的Java单例模式”相关推荐
关于拍摄语言的编程模式,哪个说法正确?
关于拍摄语言的编程模式,哪个说法正确?

关于拍摄语言的编程模式,哪个说法正确?关于Python语言的编程模式,哪个说法正确(()。A、Python采用语句式交互编程模式B.Python采用函数式编程模式C、Python采用面向对象编程模式D、以上选项都正确D是正确的。Python由荷兰数学和计算机科学研究学会的吉多·范罗苏姆于1990年代初设计,作为一门叫做ABC语言的替代品。Python提供了

2024-01-24 17:48:46
如何用Python编写一个素数环?
如何用Python编写一个素数环?

如何用Python编写一个素数环?代码:n=int(input("请输入最大数n:"))lists=[[1]]#多个素数环surplusnum=list(range(1,n+1))#剩余的数defsumisprime(x,y):#x与y之和是否是素数isprime=True#是否是素数s=x+y#和foriinrange(2,int(s**0.5)+1):

2023-12-11 17:02:40
如何用Python编写一个聊天室
如何用Python编写一个聊天室

如何用Python编写一个聊天室python聊天室(python2.7版本):暂时先给出两种版本的,tcp+udp都是分别运行server.py和client.py,就可以进行通讯了。别外还有websocket版本,这个是有web界面的和基本web服务的,如果需要的话,我会把基本的代码贴一版上来。TCP版本:socket-tcp-server.py(服务端):#

2023-12-15 14:01:15
如何检测一个JAVA程序的运行时间
如何检测一个JAVA程序的运行时间

JAVA获取一段程序运行时间abstract class GetTime { public final void getTime() { long start = System.currentTimeMillis(); runcode(); long end = System.currentTimeMillis(); System.out.println("运行时间:" + (end

2024-03-16 10:43:18
求个简单点的Java程序 100行左右。 需要解释。(求一非常简单的java 程序?)
求个简单点的Java程序 100行左右。 需要解释。(求一非常简单的java 程序?)

求个简单点的Java程序100行左右。需要解释。贪吃蛇游戏望采纳importjava.awt.Button;importjava.awt.Color;importjava.awt.GridLayout;importjava.awt.Point;importjava.awt.event.KeyEvent;importjava.awt.event.KeyListener

2024-04-01 02:32:53
如何使用python编程写一个加法计算器
如何使用python编程写一个加法计算器

如何使用python编程写一个加法计算器1、打开idle。点击file,然后点击newfile.这是创建一个新的文件。新建一个文件之后,我们输入第一行代码,使用print函数,在屏幕上打印一句话,其中字符串要使用双引号,输入法要使用英文输入法,如果符号使用中文输入法输入,就会出现错误。print("我们做一个两个整数相加的计算题!")同理,在屏幕上打印第二句话,与用户交互,提醒用户输

2024-02-14 11:12:53
java web如何去调用一个spark程序
java web如何去调用一个spark程序

javaweb如何去调用一个spark程序javaweb如何去调用一个spark程序public class HeadlinesFragment extends ListFragment { OnHeadlineSelectedListener mCallback; public interface OnHeadlineSelectedListener { void onArticle

2024-03-25 17:28:00
在python中输入五个整数例如输入23456输出的结果是二十怎么来写这个程序?
在python中输入五个整数例如输入23456输出的结果是二十怎么来写这个程序?

在python中输入五个整数例如输入23456输出的结果是二十怎么来写这个程序?你可以使用以下代码来实现这个程序:Copycode#定义一个空列表,用来存储输入的整数numbers=[]#使用循环读入5个整数foriinrange(5):#读入整数并将其转换为整型number=int(input("请输入一个整数:"))#将整数添加到列表中numbers.append(number)#计算列

2024-01-13 06:38:51