單例模式好多書上都是這么寫的:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public class SingleTon1 { private SingleTon1(){ } private static SingleTon1 instance = null ; public static SingleTon1 getInstance(){ if (instance == null ){ instance = new SingleTon1(); } return instance; } } |
但是實(shí)際開發(fā)中是不會(huì)這么寫的,因?yàn)橛幸粋€(gè)嚴(yán)重的問題,多線程并發(fā)訪問的時(shí)候,可能會(huì)產(chǎn)生多個(gè)實(shí)例!!
下面列舉幾個(gè)常用的方法:
1.使用synchronized 關(guān)鍵字
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
package singleton; public class SingleTon1 { private SingleTon1(){ } private static SingleTon1 instance = null ; //多線程問題解法一,但是效率不高!因?yàn)槊看握{(diào)用都會(huì)加鎖! public static synchronized SingleTon1 getInstance(){ if (instance == null ){ instance = new SingleTon1(); } return instance; } public void print(){ System.out.println( "thread_id:" +Thread.currentThread().getId()); } private static Object object = new Object(); //很巧妙的方法,只有在null的時(shí)候加鎖,之后就不加啦 public static SingleTon1 getInstance2(){ if (instance == null ){ synchronized (object){ instance = new SingleTon1(); } } return instance; } } |
2.加鎖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
package singleton; import java.util.concurrent.locks.ReentrantLock; public class SingleTon2 { private SingleTon2(){ } private static ReentrantLock lock = new ReentrantLock(); private static SingleTon2 instance = null ; public void print(){ System.out.println( "thread_id:" +Thread.currentThread().getId()); } public static SingleTon2 getInstance2(){ if (instance == null ){ lock.lock(); if (instance == null ){ //注意這里還要判斷下!! instance = new SingleTon2(); } lock.unlock(); } return instance; } } |
3.利用靜態(tài)變量:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
package singleton; public class SingleTon3 { public static void print(){ System.out.println( "thread_id:" +Thread.currentThread().getId()); } public static Nested getNested(){ return Nested.instance; } //這個(gè)是單例創(chuàng)建的類 static class Nested{ private Nested(){ } static Nested instance = new Nested(); } } |
以上就是常用的創(chuàng)建單例的模式:
Test測(cè)試代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
package singleton; import singleton.SingleTon3.Nested; public class Test2 { public static void main(String[] args) { // TODO Auto-generated method stub Nested singleton; Myrunnable mm = new Myrunnable(); Myrunnable m1 = new Myrunnable(); Myrunnable2 m2 = new Myrunnable2(); new Thread(m1).start(); new Thread(m2).start(); if (m1.singleton == m2.singleton){ //是同一個(gè) System.out.println( "是同一個(gè)" ); } else { System.out.println( "不是同一個(gè)" ); } } } class Myrunnable implements Runnable{ Nested singleton; @Override public void run() { // TODO Auto-generated method stub singleton = SingleTon3.getNested(); SingleTon3.print(); } } class Myrunnable2 implements Runnable{ Nested singleton; @Override public void run() { // TODO Auto-generated method stub singleton = SingleTon3.getNested(); SingleTon3.print(); } } |
輸出:
是同一個(gè)
thread_id:11
thread_id:10
以上就是對(duì)Java 單例模式的資料整理,后續(xù)繼續(xù)補(bǔ)充相關(guān)資料,謝謝大家對(duì)本站的支持!
原文鏈接:http://www.cnblogs.com/jycboy/p/5892185.html