package Thread;
/*
单例设计模式:懒汉式并发运行时的安全问题
*/
//饿汉式设计模式
class Single1{
private Single1(){}
private final static Single1 S1 = new Single1();
public static Single1 getSing(){
return S1;
}
}
//懒汉式设计模式
class Single2{
private Single2(){}
private static Single2 S2 = null;
public synchronized static Single2 getSingle(){
if(S2==null){
S2 = new Single2();
}
return S2;
}
}
class ThreadDemo implements Runnable{
public void run(){
//Single1 S =Single1.getSing();
/*
饿汉式并发运行时不会出现安全问题:1.有共享数据 实例 S1 2.但是对共享数据的操作代码已有一行,不会出现CPU切换导致的数据错误
*/
Single2 S =Single2.getSingle();
/*
懒汉式并发运行会发生并发运行时的安全问题:1.有共享数据 S2。 2对共享数据的操作代码不只一行
安全问题是:实例不再是唯一的————单例设计模式废掉
*/
}
}
public class ThreadSingle {
public static void main(String[] args){
ThreadDemo t = new ThreadDemo();
Thread T1= new Thread(t);
Thread T2 = new Thread(t);
T1.start();
T2.start();
}
}
单例设计模式就不再多说,
/*
饿汉式并发运行时不会出现安全问题:1.有共享数据 实例 S1 2.但是对共享数据的操作代码已有一行,不会出现CPU切换导致的数据错误
*/
/*
懒汉式并发运行会发生并发运行时的安全问题:1.有共享数据 S2。 2对共享数据的操作代码不只一行
安全问题是:实例不再是唯一的————单例设计模式废掉
*/
But
加入同步解决了,并发运行产生的安全问题,但是,同步的出现降低了效率(无路是哪一个路径都要去判断是否为相应的锁)
解决代码:
package Thread;
/*
单例设计模式:懒汉式并发运行时的安全问题
*/
//饿汉式设计模式
class Single1{
private Single1(){}
private final static Single1 S1 = new Single1();
public static Single1 getSing(){
return S1;
}
}
//懒汉式设计模式
class Single2{
private Single2(){}
private static Single2 S2 = null;
public static Single2 getSingle(){
if(S2==null) {
synchronized (Single2.class) {
if (S2 == null) {
S2 = new Single2();
}
}
}
return S2;
}
}
class ThreadDemo implements Runnable{
public void run(){
while(true) {
//Single1 S =Single1.getSing();
/*
饿汉式并发运行时不会出现安全问题:1.有共享数据 实例 S1 2.但是对共享数据的操作代码已有一行,不会出现CPU切换导致的数据错误
*/
Single2 S = Single2.getSingle();
/*
懒汉式并发运行会发生并发运行时的安全问题:1.有共享数据 S2。 2对共享数据的操作代码不只一行
安全问题是:实例不再是唯一的————单例设计模式废掉
*/
}
}
}
public class ThreadSingle {
public static void main(String[] args){
ThreadDemo t = new ThreadDemo();
Thread T1= new Thread(t);
Thread T2 = new Thread(t);
T1.start();
T2.start();
}
}
/懒汉式设计模式
class Single2{
private Single2(){}
private static Single2 S2 = null;
public static Single2 getSingle(){
if(S2==null) {/——————————————————————————————————————/1
synchronized (Single2.class) {/——————————————————/2
if (S2 == null) {/———————————————————————————/3
S2 = new Single2();/——————————————————————/4
}
}
}
return S2;
}
}
通过双重判断的方式,解决效率问题,减少锁的判断次数
分析:首先将线程任务设置为无穷(也可以设置一个比较大的循环次数——这样比较好理解)
线程0判断1 获取2 的锁,判断3 ,此时CPU切换,线程1判断1 ,判断2 已经被锁起来。CPU切回0 实例赋值。以后无论是哪一个线程都会在判断1 时停止。虽然看着是多了几行代码,但是就大量循环来说,是提高了效率