Java中的单例设计模式

Singleton Pattern说, 只是“定义一个只有一个实例并提供对其全局访问点的类”。
换句话说, 一个类必须确保仅创建单个实例, 并且所有其他类都可以使用单个对象。
单例设计模式有两种形式

  • 早期实例化:在加载时创建实例。
  • 延迟实例化:在需要时创建实例。
Singleton设计模式的优势
  • 因为没有在每个请求中创建对象, 所以节省了内存。只有单个实例一次又一次地被重用。
Singleton设计模式的用法
  • 单例模式主要用于多线程和数据库应用程序。它用于日志记录, 缓存, 线程池, 配置设置等。
UML的Singleton设计模式
Java中的单例设计模式

文章图片
如何创建Singleton设计模式? 要创建单例类, 我们需要具有类的静态成员, 私有构造函数和静态工厂方法。
  • 静态成员:由于静态, 它仅获取一次内存, 它包含Singleton类的实例。
  • 私有构造函数:它将阻止从类外部实例化Singleton类。
  • 静态工厂方法:此方法提供对Singleton对象的全局访问点, 并将实例返回给调用方。
了解Singleton模式的早期实例化
【Java中的单例设计模式】在这种情况下, 我们在声明静态数据成员时创建该类的实例, 因此该类的实例是在加载类时创建的。
让我们看一下使用早期实例化的单例设计模式的示例。
class A{ private static A obj=new A(); //Early, instance will be created at load time private A(){} public static A getA(){ return obj; } public void doSomething(){ //write your code } }

了解单例模式的延迟实例化
在这种情况下, 我们将在同步方法或同步块中创建该类的实例, 因此将在需要时创建该类的实例。
让我们看一下使用延迟实例化的单例设计模式的简单示例。
class A{ private static A obj; private A(){} public static A getA(){ if (obj == null){ synchronized(Singleton.class){ if (obj == null){ obj = new Singleton(); //instance will be created at request time } } } return obj; } public void doSomething(){ //write your code } }

类装载器在单例模式中的意义
如果单例类由两个类加载器加载, 则将创建两个单例类实例, 每个类加载器一个。 单例模式中序列化的意义
如果singleton类是Serializable, 则可以序列化singleton实例。序列化后, 你可以对其进行反序列化, 但不会返回单例对象。
若要解决此问题, 你需要重写强制执行单例的readResolve()方法。在对象反序列化之后立即调用它。它返回单例对象。
public class A implements Serializable { //your code of singleton protected Object readResolve() { return getA(); } }

了解单例模式的真实示例
  • 我们将创建一个JDBCSingleton类。该JDBCSingleton类包含其构造函数(私有)和自身的私有静态实例jdbc。
  • JDBCSingleton类提供了一个静态方法来将其静态实例传递给外界。现在, JDBCSingletonDemo类将使用JDBCSingleton类来获取JDBCSingleton对象。
Java中的单例设计模式

文章图片
假设:你创建了一个表userdata, 该表在mysql数据库中具有uid, uname和upassword三个字段。数据库名称是ashwinirajput, 用户名是root, 密码是ashwini。
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; class JDBCSingleton { //Step 1 // create a JDBCSingleton class. //static member holds only one instance of the JDBCSingleton class.private static JDBCSingleton jdbc; //JDBCSingleton prevents the instantiation from any other class. private JDBCSingleton() {}//Now we are providing gloabal point of access. public static JDBCSingleton getInstance() { if (jdbc==null) { jdbc=newJDBCSingleton(); } return jdbc; }// to get the connection from methods like insert, view etc. private static Connection getConnection()throws ClassNotFoundException, SQLException {Connection con=null; Class.forName("com.mysql.jdbc.Driver"); con= DriverManager.getConnection("jdbc:mysql://localhost:3306/ashwanirajput", "root", "ashwani"); return con; } //to insert the record into the database public int insert(String name, String pass) throws SQLException { Connection c=null; PreparedStatement ps=null; int recordCounter=0; try {c=this.getConnection(); ps=c.prepareStatement("insert into userdata(uname, upassword)values(?, ?)"); ps.setString(1, name); ps.setString(2, pass); recordCounter=ps.executeUpdate(); } catch (Exception e) { e.printStackTrace(); } finally{ if (ps!=null){ ps.close(); }if(c!=null){ c.close(); } } return recordCounter; }//to view the data from the database publicvoid view(String name) throws SQLException { Connection con = null; PreparedStatement ps = null; ResultSet rs = null; try {con=this.getConnection(); ps=con.prepareStatement("select * from userdata where uname=?"); ps.setString(1, name); rs=ps.executeQuery(); while (rs.next()) { System.out.println("Name= "+rs.getString(2)+"\t"+"Paasword= "+rs.getString(3)); }} catch (Exception e) { System.out.println(e); } finally{ if(rs!=null){ rs.close(); }if (ps!=null){ ps.close(); }if(con!=null){ con.close(); } } }// to update the password for the given username public int update(String name, String password) throws SQLException{ Connection c=null; PreparedStatement ps=null; int recordCounter=0; try { c=this.getConnection(); ps=c.prepareStatement(" update userdata set upassword=? where uname='"+name+"' "); ps.setString(1, password); recordCounter=ps.executeUpdate(); } catch (Exception e) {e.printStackTrace(); } finally{if (ps!=null){ ps.close(); }if(c!=null){ c.close(); } } return recordCounter; }// to delete the data from the database public int delete(int userid) throws SQLException{ Connection c=null; PreparedStatement ps=null; int recordCounter=0; try { c=this.getConnection(); ps=c.prepareStatement(" delete from userdata where uid='"+userid+"' "); recordCounter=ps.executeUpdate(); } catch (Exception e) { e.printStackTrace(); } finally{ if (ps!=null){ ps.close(); }if(c!=null){ c.close(); } } return recordCounter; } }// End of JDBCSingleton class

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; class JDBCSingletonDemo{ static int count=1; static intchoice; public static void main(String[] args) throws IOException {JDBCSingleton jdbc= JDBCSingleton.getInstance(); BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); do{ System.out.println("DATABASE OPERATIONS"); System.out.println(" --------------------- "); System.out.println(" 1. Insertion "); System.out.println(" 2. View"); System.out.println(" 3. Delete"); System.out.println(" 4. Update"); System.out.println(" 5. Exit"); System.out.print("\n"); System.out.print("Please enter the choice what you want to perform in the database: "); choice=Integer.parseInt(br.readLine()); switch(choice) {case 1:{ System.out.print("Enter the username you want to insert data into the database: "); String username=br.readLine(); System.out.print("Enter the password you want to insert data into the database: "); String password=br.readLine(); try { int i= jdbc.insert(username, password); if (i> 0) { System.out.println((count++) + " Data has been inserted successfully"); }else{ System.out.println("Data has not been inserted "); }} catch (Exception e) { System.out.println(e); }System.out.println("Press Enter key to continue..."); System.in.read(); }//End of case 1 break; case 2:{ System.out.print("Enter the username : "); String username=br.readLine(); try{ jdbc.view(username); } catch (Exception e) { System.out.println(e); } System.out.println("Press Enter key to continue..."); System.in.read(); }//End of case 2 break; case 3:{ System.out.print("Enter the userid, you want to delete: "); int userid=Integer.parseInt(br.readLine()); try { int i= jdbc.delete(userid); if (i> 0) { System.out.println((count++) + " Data has been deleted successfully"); }else{ System.out.println("Data has not been deleted"); }} catch (Exception e) { System.out.println(e); } System.out.println("Press Enter key to continue..."); System.in.read(); }//End of case 3 break; case 4:{ System.out.print("Enter the username, you want to update: "); String username=br.readLine(); System.out.print("Enter the new password "); String password=br.readLine(); try { int i= jdbc.update(username, password); if (i> 0) { System.out.println((count++) + " Data has been updated successfully"); }} catch (Exception e) { System.out.println(e); } System.out.println("Press Enter key to continue..."); System.in.read(); }// end of case 4 break; default: return; }} while (choice!=4); } }

输出量
Java中的单例设计模式

文章图片
Java中的单例设计模式

文章图片
Java中的单例设计模式

文章图片

    推荐阅读