首页 > 后端开发 > 正文

如何写一个标准的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中哪些对象都是单例模式

我爱编程网(https://www.52biancheng.com)小编还为大家带来java中哪些对象都是单例模式的相关内容。

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

1)Runtime类

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

2)Desktop类

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

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

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

以上就是我爱编程网为大家带来的如何写一个标准的Java单例模式,希望能帮助到大家!更多相关文章关注我爱编程网:www.52biancheng.com

免责声明:文章内容来自网络,如有侵权请及时联系删除。
与“如何写一个标准的Java单例模式”相关推荐
java  例如在界面上添加一个button,点击button时如何设置断点进入程序单步调式
java 例如在界面上添加一个button,点击button时如何设置断点进入程序单步调式

java例如在界面上添加一个button,点击button时如何设置断点进入程序单步调式使用Eclipse等IDE编程工具,能方便的进入调试模式。以Eclipse为例:在button的事件函数里面设置断点,用调试模式(即debugas)启动程序即可。新增:把代码贴出来吧。新增:e.getActionCommand().equals("Exit")是用来确认你是否点击的Ex

2024-05-12 13:07:51
Php设计模式如何实现(php设计模式如何实现数据分析)
Php设计模式如何实现(php设计模式如何实现数据分析)

php高级教程php高级教程导语:php是it行业语言,也是一门较热的网络技术,下面就由我为大家介绍一下php高级教程,欢迎大家阅读!一、PHP-多维数组:$cars=array(array("huawei","12","11"),array("meizu","23","12"),array("iphone","12","4"));$ti

2024-09-19 05:43:20
如何获得php当前的运行模式
如何获得php当前的运行模式

urlPHPURL地址获取函数代码端口等推荐在PHP中,获取URL地址是一个基础但重要的操作,涉及到当前脚本的路径、域名、端口等信息。以下是一些用于获取不同URL信息的代码示例。首先,获取当前脚本网址(只包含路径)的代码如下:phpfunctionGetCurUrl(){if(!empty($_SERVER["REQUEST_URI"])){$scrtName=$_S

2024-12-15 04:18:15
PHP正则表达式的使用技巧 PHP网络编程标准教程的目录
PHP正则表达式的使用技巧 PHP网络编程标准教程的目录

PHP正则表达式的使用技巧PHP正则表达式的定义用于描述字符排列和匹配模式的一种语法规则它主要用于字符串的模式分割匹配查找及替换操作PHP中的正则函数PHP中有两套正则函数两者功能差不多分别为一套是由PCRE(PerlCompatibleRegularExpression)库提供的使用preg_为前缀命名的函数一套由POSIX(PortableOperatin

2024-11-01 21:00:37
如何用java编写一个循环程序?
如何用java编写一个循环程序?

如何用java编写一个循环程序?importjava.util.*;publicclassMain{publicstaticvoidmain(String[]args){Scanners=newScanner(System.in);intsum=0;intx=s.nextInt();while(x!=0){if(x%2==1){sum+=x;

2024-04-26 19:36:07
thinkphp3.2.3重写模式怎么调也没效果
thinkphp3.2.3重写模式怎么调也没效果

web.config重写实现PHP后缀改html通过Web.config的rewrite规则设置URL重写功能,尤其适用于IIS7及以上版本。具体实例代码如下:节点的name需确保不重复。url设置为正则表达式,如^(.*)t/([0-9,a-z]*),此表达式用于匹配域名开头的任何字符,以及任何数字和字母。执行类型设为重写,实际网址写入,如{R:1}/list.asp?i

2025-02-08 12:13:32
C++的标准动态库为什么不能被PHP调用
C++的标准动态库为什么不能被PHP调用

C++的标准动态库为什么不能被PHP调用php调用C/C++动态链接库一、简介一般而言,php速度已经比较快,但是,对于一些较高级开发者而言,如果想要追求更快的速度,那毫无疑问可以通过自己写c代码,并编译为动态链接库(常为.so文件),然后php通过创建一个新的扩展(extension),并在扩展里调用该.so文件,同时对外暴露出php函数接口。在实际使用中,只要调用该函数接口,

2025-01-16 21:30:09
PHP算法:如何判断一个已知坐标点存在于一个多边形内
PHP算法:如何判断一个已知坐标点存在于一个多边形内

PHP算法:如何判断一个已知坐标点存在于一个多边形内在多边性的存储中,每一个多边形都是由一系列连续的点组成,例如保存为数组Polygon[5],表示这个多边形是由5个点组成,这5个点顺序地存储在了数组Polygon之中。就如同走路一般地划线,从数组的第一个点连到第五个点,多边行就构造出来了。在图形编程中,坐标的利用是不可忽视的。在这里判断一个点是否在多边行内部(可以包括线上)就要利用到各

2025-02-12 05:07:23