之前讲的单例模式中的懒汉模式是在调用时才会生成一个对象以供使用,
为了防止同时多个线程创建多个对象就需要考虑到线程安全的问题。
给getInstance()添加synchronized符号
public class BankTest {
static Bank b1=null;
static Bank b2=null;
public static void main(String[] args) {
Thread t1=new Thread(){
@Override
public void run() {
b1=Bank.getInstance();
}
};
Thread t2=new Thread(){
@Override
public void run() {
b2=Bank.getInstance();
}
};
t1.start();
t2.start();
//注意这里加一个睡眠,mian线程直接向下执行输出时b1、b2还没造好,等造好后再输出地址
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(b1);
System.out.println(b2);
System.out.println(b1==b2);
}
}
class Bank{
static Bank a1=null;
private Bank(){
}
//给get方法加上synchronized就可以了
public static synchronized Bank getInstance(){
if(a1==null){
a1=new Bank();
}
return a1;
}
}
同步代码块
给getInstance内的方法内容加上synchronized
public class BankTest {
static Bank b1=null;
static Bank b2=null;
public static void main(String[] args) {
Thread t1=new Thread(){
@Override
public void run() {
b1=Bank.getInstance();
}
};
Thread t2=new Thread(){
@Override
public void run() {
b2=Bank.getInstance();
}
};
t1.start();
t2.start();
//注意这里加一个睡眠,mian线程直接向下执行输出时b1、b2还没造好,等造好后再输出地址
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(b1);
System.out.println(b2);
System.out.println(b1==b2);
}
}
class Bank{
static Bank a1=null;
private Bank(){
}
//给get方法加上synchronized就可以了
public static Bank getInstance(){
synchronized (Bank.class){
if(a1==null){
a1=new Bank();
}
return a1;
}
}
}
首先考虑instance是否存在,在实例有对象的情况下直接就可以调用它,不需要每个线程进入同步代码块再创建对象,节约时间
存在指令重排问题,需要将instance声明为volatile
public class BankTest {
static Bank b1=null;
static Bank b2=null;
public static void main(String[] args) {
Thread t1=new Thread(){
@Override
public void run() {
b1=Bank.getInstance();
}
};
Thread t2=new Thread(){
@Override
public void run() {
b2=Bank.getInstance();
}
};
t1.start();
t2.start();
//注意这里加一个睡眠,mian线程直接向下执行输出时b1、b2还没造好,等造好后再输出地址
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(b1);
System.out.println(b2);
System.out.println(b1==b2);
}
}
class Bank{
static Bank a1=null;
private Bank(){
}
//给get方法加上synchronized就可以了
public static Bank getInstance(){
if(a1==null){
synchronized (Bank.class){
if(a1==null){
a1=new Bank();
}
}
}
return a1;
}
}
推荐阅读: