java靜態內部類
將某個內部類定義為靜態類,跟將其他類定義為靜態類的方法基本相同,引用規則也基本一致。不過其細節方面仍然有很大的不同。具體來說,主要有如下幾個地方要引起各位程序開發人員的注意。
(一)一般情況下,如果一個內部類不是被定義成靜態內部類,那么在定義成員變量或者成員方法的時候,是不能夠被定義成靜態成員變量與靜態成員方法的。也就是說,在非靜態內部類中不可以聲明靜態成員。
(二)一般非靜態外部類可以隨意訪問其外部類的成員變量以及方法(包括聲明為private的方法),但是如果一個內部類被聲明為static,則其在訪問包括自身的外部類會有諸多的限制。靜態內部類不能訪問其外部類的非靜態成員變量和方法。
(三)在一個類中創建非靜態成員內部類的時候,有一個強制性的規定,即內部類的實例一定要綁定在外部類的實例中。然后要在一個外部類中定義一個靜態的內部類,不需要利用關鍵字new來創建內部類的實例。即在創建靜態類內部對象時,不需要其外部類的對象。
java在實現LinkedList時使用了如下內部類:
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
|
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable { ........ private static class Entry<E> { E element; Entry<E> next; Entry<E> previous; Entry(E element, Entry<E> next, Entry<E> previous) { this .element = element; this .next = next; this .previous = previous; } } private Entry<E> addBefore(E e, Entry<E> entry) { Entry<E> newEntry = new Entry<E>(e, entry, entry.previous); newEntry.previous.next = newEntry; newEntry.next.previous = newEntry; size++; modCount++; return newEntry; } ........ } |
這里即靜態內部類的典型用法
java同步工具類
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
/** * 需要啟動多個線程把接口數據分批導入目標,要求 * 每次執行的時候必須保證前一次任務已結束,處理這個需求的方式有很多種,其實質即 * 線程間同步問題,正好這兩天我也在關注線程同步相關的東東,jdk提供了不少的線程 * 同步工具類,CountDownLatch:一個同步輔助類,在完成一組正在其他線程中執行的 * 操作之前,它允許一個或多個線程一直等待。 * 用給定的計數 初始化 CountDownLatch。由于調用了 countDown() 方法,所以在當前計數到達零之前, * await 方法會一直受阻塞。之后,會釋放所有等待的線程,await 的所有后續調用都將立即返回。 * 這種現象只出現一次——計數無法被重置(這點很重要哦)。如果需要重置計數,請考慮使用 CyclicBarrier。 * 下面是一個簡單的例子來模擬該需求,當然可能因為為了模擬場景,會有一些不合理的地方,這里主要闡述 * CountDownLatch同步,關于CountDownLatch的源碼將在后面來分析,其主要涉及AbstractQueuedSynchronizer * 這個類,他的類容相對比較復雜 * **/ import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.concurrent.CountDownLatch; public class Driver { static List<Integer> strList = null ; int k = 0 ; static { //模擬數據 strList = new ArrayList<Integer>(); for ( int i = 0 ; i < 50 ; i++) { strList.add(i); } } public static void main(String args[]) { boolean isEnd = true ; //為了驗證正確性,只執行20次 int count= 0 ; Driver d = new Driver(); while (isEnd && strList.size() > 0 &&count< 20 ) { CountDownLatch startSignal = new CountDownLatch( 1 ); final CountDownLatch doneSignal = new CountDownLatch( 5 ); for ( int i = 0 ; i < 5 ; ++i) { new Thread(d. new Worker(startSignal, doneSignal,i)).start(); } //計數減1 子線程Worker可以執行 startSignal.countDown(); try { new Thread( new Runnable() { Random r = new Random(); @Override public void run() { try { //主線程阻塞 知道所有子線程將doneSignal清零 doneSignal.await(); } catch (InterruptedException e) { e.printStackTrace(); } while (strList.size()<= 0 ){ int pos = r.nextInt( 1000 ); strList.clear(); for ( int i = pos; i < pos + 50 ; i++) { strList.add(i); } } } }).start(); isEnd = true ; } catch (Exception e) { e.printStackTrace(); } count++; } } class Worker implements Runnable { private final CountDownLatch startSignal; private final CountDownLatch doneSignal; private int i; Worker(CountDownLatch startSignal, CountDownLatch doneSignal, int i) { this .startSignal = startSignal; this .doneSignal = doneSignal; this .i=i; } public void run() { try { // 等待主線程執行countDown startSignal.await(); doWork(); //計數減1 doneSignal.countDown(); } catch (InterruptedException ex) { } // return; } void doWork() { synchronized (strList) { int start=(i)*( 50 / 5 ); int end=(i+ 1 )*( 50 / 5 ); for ( int i = start; i < end; i++) { System.out.println(strList.get(i) + "---" + "已被刪除" ); } } } } } |