单例模式(Singleton)的同步锁synchronized
前言
当两个人同时操作一条数据时会引起并发,这时候可以用synchronized锁住代码块,进行相关处理。
注:JPAUtil根据ID查询不是实时数据,可能里面有缓存。后改成DBTool 原生查询sql,才查出实时数据。
DBTool tool = new DBTool();
Record[] r = tool.executeQuery("select state from tableName where uuid='" + uuid+ "'", null);
单例模式,有“懒汉式”和“饿汉式”两种。
1、懒汉式
单例类的实例在第一次被引用时候才被初始化。
1 public class Singleton { 2 private static Singleton instance=null; 3 4 private Singleton() { 5 6 } 7 8 public static Singleton getInstance(){ 9 if (instance == null) { 10 instance = new Singleton(); 11 } 12 13 return instance; 14 } 15 }
2、饿汉式
单例类的实例在加载的时候就被初始化。
1 public class Singleton { 2 private static Singleton instance = new Singleton(); 3 4 private Singleton() { 5 6 } 7 8 public static Singleton getInstance(){ 9 return instance; 10 } 11 }
在单线程中,上面两种形式基本可以满足要求了,但是在多线程环境下,单例类就有可能会失效,这个时候就要对其加锁了,来确保线程安全。
对线程加锁用的synchronized关键字,这个关键字的用法主要也分为两种:
一种是加在方法名之前,形如:public synchronized void methodeName(params){……};
二是声明同步块,形如:public void methodeName(params){synchronized(this){……}};
下面是对懒汉式单例类加上线程同步的实现:
1 public class Singleton { 2 private static Singleton instance=null; 3 4 private Singleton() { 5 6 } 7 8 public synchronized static Singleton getInstance(){ 9 if (instance == null) { 10 instance = new Singleton(); 11 } 12 13 return instance; 14 } 15 }
这种方式效率比较低,性能不是太好,不过也可以用,因为是对整个方法加上了线程同步,其实只要在new的时候考虑线程同步就行了,这种方法不推荐使用。
同步代码块:
1 public class Singleton { 2 private static Singleton instance; 3 private final static Object syncLock = new Object(); 4 5 private Singleton() { 6 7 } 8 9 public static Singleton getInstance(){ 10 if (instance == null) { 11 synchronized (syncLock) { 12 if (instance == null) { 13 instance = new Singleton(); 14 } 15 } 16 } 17 18 return instance; 19 } 20 }
synchronized同步块括号中的锁定对象是采用的一个无关的Object类实例,而不是采用this,因为getInstance是一个静态方法,在它内部不能使用未静态的或者未实例的类对象,因此也可以用下面的方法来实现:
1 public class Singleton { 2 private static Singleton instance; 3 4 private Singleton() { 5 6 } 7 8 public static Singleton getInstance(){ 9 if (instance == null) { 10 synchronized (Singleton.class) { 11 if (instance == null) { 12 instance = new Singleton(); 13 } 14 } 15 } 16 17 return instance; 18 } 19 }