单例模式是一种常见的设计模式,一般有三种方式,单例模式具有如下特点:
1.在类的属性中,自己初始化一个静态的私有的类实例
2.将自己的构造方法写成private的方式,拒绝其他类或者操作再次使用构造函数将单例类再次实例化
3.向外界提供一个公开的方法来获取自己的唯一单实例
用一句话来概括就是:单例模式类有且仅有一个自己初始化的实例,通过方法向外界提供该实例
那么单例模式有什么用途呢或者说单例模式都有哪些常见的呢?
你比如说,我们电脑中的打印机管理器,电脑里面只有一个该管理器的,但是我们的电脑可以同时连接上多个打印机,管理器的作用就是管理打印机工作情况,避免出现两个打印机同时工作的时候,会出现打印冲突的现象,管理器主要就干这个事的,我们电脑里面这一类的管理器,内存池等等都是单例模式的一种表现,单例模式就是为了避免同时运行时产生冲突。常见的单例模式有三种,这里暂时先介绍两种,因为第三种我还没来得及研究呢!
1.饿汉单例模式
2.懒汉式单例模式
但是很显然,上面的这个写法是非线程安全的。
1.在类的属性中,自己初始化一个静态的私有的类实例
2.将自己的构造方法写成private的方式,拒绝其他类或者操作再次使用构造函数将单例类再次实例化
3.向外界提供一个公开的方法来获取自己的唯一单实例
用一句话来概括就是:单例模式类有且仅有一个自己初始化的实例,通过方法向外界提供该实例
那么单例模式有什么用途呢或者说单例模式都有哪些常见的呢?
你比如说,我们电脑中的打印机管理器,电脑里面只有一个该管理器的,但是我们的电脑可以同时连接上多个打印机,管理器的作用就是管理打印机工作情况,避免出现两个打印机同时工作的时候,会出现打印冲突的现象,管理器主要就干这个事的,我们电脑里面这一类的管理器,内存池等等都是单例模式的一种表现,单例模式就是为了避免同时运行时产生冲突。常见的单例模式有三种,这里暂时先介绍两种,因为第三种我还没来得及研究呢!
1.饿汉单例模式
01.pubic class Demo(){
02. private static Demo demo = new Demo();//创建private、static的本类的实例
03. private Demo(){} //private私有的构造方法,拒绝初始化第二个实例
04. public Demo getDemo(){ //公共开放的获取实例的方法
05. return demo;
06. }
07. //其他方法和操作
08.}
2.懒汉式单例模式
01.pubic class Demo(){
02. private static Demo demo = null;
03. private Demo(){} //private私有的构造方法,拒绝初始化第二个实例
04. public Demo getDemo(){ //公共开放的获取实例的方法
05. if(demo == null)
06. demo = new Demo();
07. return demo;
08. }
09. //其他方法和操作
10.}
但是很显然,上面的这个写法是非线程安全的。
小知识:线程安全
线程安全就是我的这段代码在多个线程中同时被运行了,多线程运行的结果与单线程情况下运行出来的结果是不是一致的,如果不一致,那么我们就可以说这是非线程安全的,反之就是个线程安全的,上面的这个代码,很显然,是非线程安全的,饿汉式写法也是如此,非线程安全的。
换句话说,就是如果一段代码的运行,对线程来说属于原子操作或者在不同的进程之间来回切换的不会造成结果的二义性,那么就是线程安全的,这时候我们不需要考虑同步运行的情况了。
3.登记式单例模式
有待补充这种单例模式
下面就来一个实例吧!单例模式最常见的写法我觉得应该就是jdbc获取connection的时候了吧,下面就写一个这几天我在实习时过程中,看到同时给我些的这个东西,我也刚开始实习,这些我都还要继续努力学习才能够会呢!!
例子:
项目中,驱动的环境需要手动去设置和添加了,代码如下:
01.public final class Server {
02. /**
03. * ConnectionFactory对象
04. */
05. private ConnectionFactory factory = null;
06.
07. /**
08. * 单例模式
09. */
10. private static Server svr = new Server();
11.
12. /**
13. * 构造方法
14. */
15. private Server() {
16.
17. }
18.
19. /**
20. * 获取单例模式实体
21. *
22. * @return Server
23. */
24. public static Server getInstance() {
25. return svr;
26. }
27.
28. /**
29. * 获取数据库连接池工厂
30. *
31. * @return ConnectionFactory
32. */
33. public synchronized ConnectionFactory getConnFactory() {
34. if (factory == null) {
35. try {
36. MiniProperties ppt = new MiniProperties();
37. ppt.load(Server.class.getResourceAsStream("/jdbc.properties"));<span style="white-space:pre"> </span>//这里需要注意路径,改代码详细信息在下面一段代码中
38. factory = new PoolConnectionFactory("test", ppt);
39. } catch (Exception e) {
40. throw new RuntimeException("jdbc配置文件读取失败!");
41. }
42. }
43. return factory;
44. }
45.
46. public static void closeResource(Connection conn, Statement stmt,
47. ResultSet rs) {
48. if (rs != null) {
49. try {
50. rs.close();
51. } catch (Exception e) {
52.
53. }
54. }
55. if (stmt != null) {
56. try {
57. stmt.close();
58. } catch (Exception e) {
59.
60. }
61. }
62. if (conn != null) {
63. try {
64. conn.close();
65. } catch (Exception e) {
66.
67. }
68. }
69. }
70.}