单例模式
public class SingletonObject {
int num = 100;
private static SingletonObject mInstance;
private SingletonObject(){}
public static SingletonObject getInstance(){
if (mInstance==null) {
mInstance = new SingletonObject();
}
return mInstance;
}
public void showHello(String msg){
System.out.println(msg);
}
public boolean saleOne() {
if (num<=0) {
System.out.println("Ticket Over!!!");
return false;
}else {
num--;
System.out.println("remain be left ticket:"+num);
return true;
}
}
public void resetTicket(int num){
this.num = num;
}
}
public class SingletonDemo {
public static void main(String[] args){
SingletonObject singletonObject = SingletonObject.getInstance();
while(singletonObject.saleOne()){
}
}
}
结果如下图
remain be left ticket:99
remain be left ticket:98
remain be left ticket:97
remain be left ticket:96
remain be left ticket:95
remain be left ticket:94
remain be left ticket:93
remain be left ticket:92
remain be left ticket:91
remain be left ticket:90
remain be left ticket:89
remain be left ticket:88
remain be left ticket:87
remain be left ticket:86
remain be left ticket:85
remain be left ticket:84
remain be left ticket:83
remain be left ticket:82
remain be left ticket:81
remain be left ticket:80
remain be left ticket:79
remain be left ticket:78
remain be left ticket:77
remain be left ticket:76
remain be left ticket:75
remain be left ticket:74
remain be left ticket:73
remain be left ticket:72
remain be left ticket:71
remain be left ticket:70
remain be left ticket:69
remain be left ticket:68
remain be left ticket:67
remain be left ticket:66
remain be left ticket:65
remain be left ticket:64
remain be left ticket:63
remain be left ticket:62
remain be left ticket:61
remain be left ticket:60
remain be left ticket:59
remain be left ticket:58
remain be left ticket:57
remain be left ticket:56
remain be left ticket:55
remain be left ticket:54
remain be left ticket:53
remain be left ticket:52
remain be left ticket:51
remain be left ticket:50
remain be left ticket:49
remain be left ticket:48
remain be left ticket:47
remain be left ticket:46
remain be left ticket:45
remain be left ticket:44
remain be left ticket:43
remain be left ticket:42
remain be left ticket:41
remain be left ticket:40
remain be left ticket:39
remain be left ticket:38
remain be left ticket:37
remain be left ticket:36
remain be left ticket:35
remain be left ticket:34
remain be left ticket:33
remain be left ticket:32
remain be left ticket:31
remain be left ticket:30
remain be left ticket:29
remain be left ticket:28
remain be left ticket:27
remain be left ticket:26
remain be left ticket:25
remain be left ticket:24
remain be left ticket:23
remain be left ticket:22
remain be left ticket:21
remain be left ticket:20
remain be left ticket:19
remain be left ticket:18
remain be left ticket:17
remain be left ticket:16
remain be left ticket:15
remain be left ticket:14
remain be left ticket:13
remain be left ticket:12
remain be left ticket:11
remain be left ticket:10
remain be left ticket:9
remain be left ticket:8
remain be left ticket:7
remain be left ticket:6
remain be left ticket:5
remain be left ticket:4
remain be left ticket:3
remain be left ticket:2
remain be left ticket:1
remain be left ticket:0
Ticket Over!!!
这个看上去是没有问题的,如果加入了多线程取票呢
public class SingletonDemo { public static void main(String[] args){ thread1.start(); thread2.start(); // SingletonObject singletonObject = SingletonObject.getInstance(); // while(singletonObject.saleOne()){ // // } } static Thread thread2 = new Thread(new Runnable() { @Override public void run() { SingletonObject singletonObject = SingletonObject.getInstance(); while(singletonObject.saleOne("thread2")){ } } }); static Thread thread1 = new Thread(new Runnable() { @Override public void run() { SingletonObject singletonObject = SingletonObject.getInstance(); while(singletonObject.saleOne("Thread1")){ } } }); }
结果如下
Thread1:remain be left ticket:99
thread2:remain be left ticket:99
thread2:remain be left ticket:98
Thread1:remain be left ticket:98
thread2:remain be left ticket:97
Thread1:remain be left ticket:97
thread2:remain be left ticket:96
thread2:remain be left ticket:95
Thread1:remain be left ticket:96
thread2:remain be left ticket:94
Thread1:remain be left ticket:95
Thread1:remain be left ticket:94
Thread1:remain be left ticket:93
Thread1:remain be left ticket:92
thread2:remain be left ticket:93
Thread1:remain be left ticket:91
thread2:remain be left ticket:92
thread2:remain be left ticket:91
Thread1:remain be left ticket:90
Thread1:remain be left ticket:89
Thread1:remain be left ticket:88
Thread1:remain be left ticket:87
Thread1:remain be left ticket:86
Thread1:remain be left ticket:85
Thread1:remain be left ticket:84
Thread1:remain be left ticket:83
Thread1:remain be left ticket:82
Thread1:remain be left ticket:81
Thread1:remain be left ticket:80
Thread1:remain be left ticket:79
Thread1:remain be left ticket:78
Thread1:remain be left ticket:77
Thread1:remain be left ticket:76
Thread1:remain be left ticket:75
Thread1:remain be left ticket:74
Thread1:remain be left ticket:73
Thread1:remain be left ticket:72
Thread1:remain be left ticket:71
Thread1:remain be left ticket:70
Thread1:remain be left ticket:69
Thread1:remain be left ticket:68
Thread1:remain be left ticket:67
Thread1:remain be left ticket:66
Thread1:remain be left ticket:65
Thread1:remain be left ticket:64
Thread1:remain be left ticket:63
Thread1:remain be left ticket:62
Thread1:remain be left ticket:61
Thread1:remain be left ticket:60
Thread1:remain be left ticket:59
Thread1:remain be left ticket:58
Thread1:remain be left ticket:57
Thread1:remain be left ticket:56
Thread1:remain be left ticket:55
Thread1:remain be left ticket:54
Thread1:remain be left ticket:53
Thread1:remain be left ticket:52
Thread1:remain be left ticket:51
Thread1:remain be left ticket:50
Thread1:remain be left ticket:49
Thread1:remain be left ticket:48
Thread1:remain be left ticket:47
Thread1:remain be left ticket:46
Thread1:remain be left ticket:45
Thread1:remain be left ticket:44
Thread1:remain be left ticket:43
Thread1:remain be left ticket:42
Thread1:remain be left ticket:41
Thread1:remain be left ticket:40
Thread1:remain be left ticket:39
Thread1:remain be left ticket:38
Thread1:remain be left ticket:37
Thread1:remain be left ticket:36
Thread1:remain be left ticket:35
Thread1:remain be left ticket:34
Thread1:remain be left ticket:33
Thread1:remain be left ticket:32
Thread1:remain be left ticket:31
Thread1:remain be left ticket:30
Thread1:remain be left ticket:29
Thread1:remain be left ticket:28
Thread1:remain be left ticket:27
Thread1:remain be left ticket:26
Thread1:remain be left ticket:25
Thread1:remain be left ticket:24
Thread1:remain be left ticket:23
Thread1:remain be left ticket:22
Thread1:remain be left ticket:21
Thread1:remain be left ticket:20
Thread1:remain be left ticket:19
Thread1:remain be left ticket:18
Thread1:remain be left ticket:17
Thread1:remain be left ticket:16
Thread1:remain be left ticket:15
Thread1:remain be left ticket:14
Thread1:remain be left ticket:13
thread2:remain be left ticket:90
Thread1:remain be left ticket:12
Thread1:remain be left ticket:11
Thread1:remain be left ticket:10
Thread1:remain be left ticket:9
Thread1:remain be left ticket:8
Thread1:remain be left ticket:7
Thread1:remain be left ticket:6
Thread1:remain be left ticket:5
Thread1:remain be left ticket:4
Thread1:remain be left ticket:3
thread2:remain be left ticket:89
thread2:remain be left ticket:88
thread2:remain be left ticket:87
thread2:remain be left ticket:86
thread2:remain be left ticket:85
thread2:remain be left ticket:84
thread2:remain be left ticket:83
thread2:remain be left ticket:82
thread2:remain be left ticket:81
thread2:remain be left ticket:80
thread2:remain be left ticket:79
thread2:remain be left ticket:78
thread2:remain be left ticket:77
thread2:remain be left ticket:76
thread2:remain be left ticket:75
thread2:remain be left ticket:74
thread2:remain be left ticket:73
thread2:remain be left ticket:72
thread2:remain be left ticket:71
thread2:remain be left ticket:70
thread2:remain be left ticket:69
Thread1:remain be left ticket:2
Thread1:remain be left ticket:1
Thread1:remain be left ticket:0
Thread1:Ticket Over!!!
thread2:remain be left ticket:68
thread2:remain be left ticket:67
thread2:remain be left ticket:66
thread2:remain be left ticket:65
thread2:remain be left ticket:64
thread2:remain be left ticket:63
thread2:remain be left ticket:62
thread2:remain be left ticket:61
thread2:remain be left ticket:60
thread2:remain be left ticket:59
thread2:remain be left ticket:58
thread2:remain be left ticket:57
thread2:remain be left ticket:56
thread2:remain be left ticket:55
thread2:remain be left ticket:54
thread2:remain be left ticket:53
thread2:remain be left ticket:52
thread2:remain be left ticket:51
thread2:remain be left ticket:50
thread2:remain be left ticket:49
thread2:remain be left ticket:48
thread2:remain be left ticket:47
thread2:remain be left ticket:46
thread2:remain be left ticket:45
thread2:remain be left ticket:44
thread2:remain be left ticket:43
thread2:remain be left ticket:42
thread2:remain be left ticket:41
thread2:remain be left ticket:40
thread2:remain be left ticket:39
thread2:remain be left ticket:38
thread2:remain be left ticket:37
thread2:remain be left ticket:36
thread2:remain be left ticket:35
thread2:remain be left ticket:34
thread2:remain be left ticket:33
thread2:remain be left ticket:32
thread2:remain be left ticket:31
thread2:remain be left ticket:30
thread2:remain be left ticket:29
thread2:remain be left ticket:28
thread2:remain be left ticket:27
thread2:remain be left ticket:26
thread2:remain be left ticket:25
thread2:remain be left ticket:24
thread2:remain be left ticket:23
thread2:remain be left ticket:22
thread2:remain be left ticket:21
thread2:remain be left ticket:20
thread2:remain be left ticket:19
thread2:remain be left ticket:18
thread2:remain be left ticket:17
thread2:remain be left ticket:16
thread2:remain be left ticket:15
thread2:remain be left ticket:14
thread2:remain be left ticket:13
thread2:remain be left ticket:12
thread2:remain be left ticket:11
thread2:remain be left ticket:10
thread2:remain be left ticket:9
thread2:remain be left ticket:8
thread2:remain be left ticket:7
thread2:remain be left ticket:6
thread2:remain be left ticket:5
thread2:remain be left ticket:4
thread2:remain be left ticket:3
thread2:remain be left ticket:2
thread2:remain be left ticket:1
thread2:remain be left ticket:0
thread2:Ticket Over!!!
卖了200张票啊!!!
这就是线程带来的问题,现在对如下地方做出改变
public synchronized static SingletonObject getInstance(){
if (mInstance==null) {
mInstance = new SingletonObject();
}
return mInstance;
}
结果
thread2:remain be left ticket:98
thread2:remain be left ticket:97
Thread1:remain be left ticket:98
thread2:remain be left ticket:96
Thread1:remain be left ticket:95
thread2:remain be left ticket:94
Thread1:remain be left ticket:93
thread2:remain be left ticket:92
Thread1:remain be left ticket:91
thread2:remain be left ticket:90
thread2:remain be left ticket:88
thread2:remain be left ticket:87
thread2:remain be left ticket:86
thread2:remain be left ticket:85
thread2:remain be left ticket:84
thread2:remain be left ticket:83
thread2:remain be left ticket:82
thread2:remain be left ticket:81
thread2:remain be left ticket:80
thread2:remain be left ticket:79
Thread1:remain be left ticket:89
Thread1:remain be left ticket:77
Thread1:remain be left ticket:76
Thread1:remain be left ticket:75
Thread1:remain be left ticket:74
Thread1:remain be left ticket:73
Thread1:remain be left ticket:72
Thread1:remain be left ticket:71
thread2:remain be left ticket:78
Thread1:remain be left ticket:70
Thread1:remain be left ticket:68
Thread1:remain be left ticket:67
thread2:remain be left ticket:69
thread2:remain be left ticket:65
thread2:remain be left ticket:64
thread2:remain be left ticket:63
thread2:remain be left ticket:62
thread2:remain be left ticket:61
thread2:remain be left ticket:60
thread2:remain be left ticket:59
Thread1:remain be left ticket:66
Thread1:remain be left ticket:57
Thread1:remain be left ticket:56
Thread1:remain be left ticket:55
Thread1:remain be left ticket:54
Thread1:remain be left ticket:53
Thread1:remain be left ticket:52
Thread1:remain be left ticket:51
Thread1:remain be left ticket:50
Thread1:remain be left ticket:49
Thread1:remain be left ticket:48
thread2:remain be left ticket:58
Thread1:remain be left ticket:47
Thread1:remain be left ticket:45
Thread1:remain be left ticket:44
Thread1:remain be left ticket:43
Thread1:remain be left ticket:42
Thread1:remain be left ticket:41
Thread1:remain be left ticket:40
Thread1:remain be left ticket:39
Thread1:remain be left ticket:38
thread2:remain be left ticket:46
thread2:remain be left ticket:36
thread2:remain be left ticket:35
thread2:remain be left ticket:34
thread2:remain be left ticket:33
thread2:remain be left ticket:32
thread2:remain be left ticket:31
Thread1:remain be left ticket:37
Thread1:remain be left ticket:29
thread2:remain be left ticket:30
thread2:remain be left ticket:27
thread2:remain be left ticket:26
thread2:remain be left ticket:25
thread2:remain be left ticket:24
thread2:remain be left ticket:23
thread2:remain be left ticket:22
thread2:remain be left ticket:21
thread2:remain be left ticket:20
thread2:remain be left ticket:19
thread2:remain be left ticket:18
thread2:remain be left ticket:17
thread2:remain be left ticket:16
thread2:remain be left ticket:15
thread2:remain be left ticket:14
thread2:remain be left ticket:13
thread2:remain be left ticket:12
thread2:remain be left ticket:11
thread2:remain be left ticket:10
thread2:remain be left ticket:9
thread2:remain be left ticket:8
thread2:remain be left ticket:7
thread2:remain be left ticket:6
thread2:remain be left ticket:5
thread2:remain be left ticket:4
thread2:remain be left ticket:3
thread2:remain be left ticket:2
thread2:remain be left ticket:1
thread2:remain be left ticket:0
thread2:Ticket Over!!!
Thread1:remain be left ticket:28
Thread1:Ticket Over!!!
发现依然不对啊,打印两个单例对象的引用看是否单例,
com.grd.singleton.SingletonObject@2be437ef
与com.grd.singleton.SingletonObject@2be437ef
这是同一个对象没错啊,那问题出在了哪呢?对售票的方法同样加上线程锁 synchronized(上面对于getInstance加上线程锁后已经是同一个对象了)。结果如下com.grd.singleton.SingletonObject@1fd1fb58
com.grd.singleton.SingletonObject@1fd1fb58
thread2:remain be left ticket:99
thread2:remain be left ticket:98
thread2:remain be left ticket:97
thread2:remain be left ticket:96
thread2:remain be left ticket:95
thread2:remain be left ticket:94
thread2:remain be left ticket:93
thread2:remain be left ticket:92
thread2:remain be left ticket:91
thread2:remain be left ticket:90
thread2:remain be left ticket:89
thread2:remain be left ticket:88
thread2:remain be left ticket:87
thread2:remain be left ticket:86
thread2:remain be left ticket:85
thread2:remain be left ticket:84
thread2:remain be left ticket:83
thread2:remain be left ticket:82
thread2:remain be left ticket:81
thread2:remain be left ticket:80
thread2:remain be left ticket:79
thread2:remain be left ticket:78
thread2:remain be left ticket:77
thread2:remain be left ticket:76
thread2:remain be left ticket:75
thread2:remain be left ticket:74
thread2:remain be left ticket:73
thread2:remain be left ticket:72
thread2:remain be left ticket:71
thread2:remain be left ticket:70
thread2:remain be left ticket:69
thread2:remain be left ticket:68
thread2:remain be left ticket:67
thread2:remain be left ticket:66
thread2:remain be left ticket:65
thread2:remain be left ticket:64
thread2:remain be left ticket:63
thread2:remain be left ticket:62
thread2:remain be left ticket:61
thread2:remain be left ticket:60
thread2:remain be left ticket:59
thread2:remain be left ticket:58
thread2:remain be left ticket:57
thread2:remain be left ticket:56
thread2:remain be left ticket:55
thread2:remain be left ticket:54
thread2:remain be left ticket:53
thread2:remain be left ticket:52
thread2:remain be left ticket:51
thread2:remain be left ticket:50
thread2:remain be left ticket:49
thread2:remain be left ticket:48
thread2:remain be left ticket:47
thread2:remain be left ticket:46
thread2:remain be left ticket:45
thread2:remain be left ticket:44
thread2:remain be left ticket:43
thread2:remain be left ticket:42
thread2:remain be left ticket:41
thread2:remain be left ticket:40
thread2:remain be left ticket:39
thread2:remain be left ticket:38
thread2:remain be left ticket:37
thread2:remain be left ticket:36
thread2:remain be left ticket:35
thread2:remain be left ticket:34
thread2:remain be left ticket:33
thread2:remain be left ticket:32
thread2:remain be left ticket:31
thread2:remain be left ticket:30
thread2:remain be left ticket:29
thread2:remain be left ticket:28
thread2:remain be left ticket:27
thread2:remain be left ticket:26
thread2:remain be left ticket:25
thread2:remain be left ticket:24
thread2:remain be left ticket:23
thread2:remain be left ticket:22
thread2:remain be left ticket:21
thread2:remain be left ticket:20
thread2:remain be left ticket:19
thread2:remain be left ticket:18
thread2:remain be left ticket:17
thread2:remain be left ticket:16
thread2:remain be left ticket:15
thread2:remain be left ticket:14
thread2:remain be left ticket:13
thread2:remain be left ticket:12
thread2:remain be left ticket:11
thread2:remain be left ticket:10
thread2:remain be left ticket:9
thread2:remain be left ticket:8
thread2:remain be left ticket:7
thread2:remain be left ticket:6
thread2:remain be left ticket:5
thread2:remain be left ticket:4
thread2:remain be left ticket:3
thread2:remain be left ticket:2
thread2:remain be left ticket:1
thread2:remain be left ticket:0
thread2:Ticket Over!!!
Thread1:Ticket Over!!!
1、懒汉式线程不安全,就如我上面的第一种方式。
2、懒汉式线程安全,如上方第二种直接对getInstance()添加线程锁,但是影响效率,只有在第一次创建开始但没创建完时才需要线程安全,所以对于效率影响比较大。
3、恶汉式,使用静态代码块直接在类加载时就初始化了对象,在类中如下
public static SingletonObject instance = new SingletonInstance();
如果一直不使用类对象的话就会显得浪费内存。不太推荐。
4.双重校验
public static SingletonObject getInstance1(){
if (mInstance==null) {
synchronized (SingletonObject.class) {
if (mInstance==null) {
mInstance = new SingletonObject();
}
}
}
return mInstance;
}
这种方法会进行两次为空检查,以及对创建代码加锁的机制。修改对应的代码运行如下:
com.grd.singleton.SingletonObject@1a6dce07
thread2:remain be left ticket:99
com.grd.singleton.SingletonObject@1a6dce07
thread2:remain be left ticket:98
thread2:remain be left ticket:97
thread2:remain be left ticket:96
thread2:remain be left ticket:95
thread2:remain be left ticket:94
thread2:remain be left ticket:93
thread2:remain be left ticket:92
thread2:remain be left ticket:91
thread2:remain be left ticket:90
thread2:remain be left ticket:89
thread2:remain be left ticket:88
thread2:remain be left ticket:87
thread2:remain be left ticket:86
thread2:remain be left ticket:85
thread2:remain be left ticket:84
thread2:remain be left ticket:83
thread2:remain be left ticket:82
thread2:remain be left ticket:81
thread2:remain be left ticket:80
thread2:remain be left ticket:79
thread2:remain be left ticket:78
thread2:remain be left ticket:77
thread2:remain be left ticket:76
thread2:remain be left ticket:75
thread2:remain be left ticket:74
thread2:remain be left ticket:73
thread2:remain be left ticket:72
thread2:remain be left ticket:71
thread2:remain be left ticket:70
thread2:remain be left ticket:69
thread2:remain be left ticket:68
thread2:remain be left ticket:67
thread2:remain be left ticket:66
thread2:remain be left ticket:65
thread2:remain be left ticket:64
thread2:remain be left ticket:63
thread2:remain be left ticket:62
thread2:remain be left ticket:61
thread2:remain be left ticket:60
thread2:remain be left ticket:59
thread2:remain be left ticket:58
thread2:remain be left ticket:57
thread2:remain be left ticket:56
thread2:remain be left ticket:55
thread2:remain be left ticket:54
thread2:remain be left ticket:53
thread2:remain be left ticket:52
thread2:remain be left ticket:51
thread2:remain be left ticket:50
thread2:remain be left ticket:49
thread2:remain be left ticket:48
thread2:remain be left ticket:47
thread2:remain be left ticket:46
thread2:remain be left ticket:45
thread2:remain be left ticket:44
thread2:remain be left ticket:43
thread2:remain be left ticket:42
thread2:remain be left ticket:41
thread2:remain be left ticket:40
thread2:remain be left ticket:39
thread2:remain be left ticket:38
thread2:remain be left ticket:37
thread2:remain be left ticket:36
thread2:remain be left ticket:35
thread2:remain be left ticket:34
thread2:remain be left ticket:33
thread2:remain be left ticket:32
thread2:remain be left ticket:31
thread2:remain be left ticket:30
thread2:remain be left ticket:29
thread2:remain be left ticket:28
thread2:remain be left ticket:27
thread2:remain be left ticket:26
thread2:remain be left ticket:25
thread2:remain be left ticket:24
thread2:remain be left ticket:23
thread2:remain be left ticket:22
thread2:remain be left ticket:21
thread2:remain be left ticket:20
thread2:remain be left ticket:19
thread2:remain be left ticket:18
thread2:remain be left ticket:17
thread2:remain be left ticket:16
thread2:remain be left ticket:15
thread2:remain be left ticket:14
thread2:remain be left ticket:13
thread2:remain be left ticket:12
thread2:remain be left ticket:11
thread2:remain be left ticket:10
thread2:remain be left ticket:9
thread2:remain be left ticket:8
thread2:remain be left ticket:7
thread2:remain be left ticket:6
thread2:remain be left ticket:5
thread2:remain be left ticket:4
thread2:remain be left ticket:3
thread2:remain be left ticket:2
thread2:remain be left ticket:1
thread2:remain be left ticket:0
thread2:Ticket Over!!!
Thread1:Ticket Over!!!
5、静态内部类
private static class InstanceHolder{
private final static SingletonObject INSTANCE = new SingletonObject();
}
public static SingletonObject getInstance2(){
return InstanceHolder.INSTANCE;
}
修改demo类中代码运行正常。
6、枚举
public enum SingletonObject1 {
INSTANCE;
int num = 100;
public synchronized boolean saleOne(String threadName) {
if (num<=0) {
System.out.println(threadName+":Ticket Over!!!");
return false;
}else {
num--;
System.out.println(threadName+":remain be left ticket:"+num);
return true;
}
}
}