1、有界緩存的基類
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
|
package cn.xf.cp.ch14; /** * *功能:有界緩存實現基類 *時間:下午2:20:00 *文件:BaseBoundedBuffer.java *@author Administrator * * @param <V> */ public class BaseBoundedBuffer<V> { private final V[] buf; private int tail; private int head; private int count; public BaseBoundedBuffer( int capacity) { //初始化數組 this .buf = (V[]) new Object[capacity]; } //放入一個數據,final方法無法被重寫 protected synchronized final void doPut(V v) { buf[tail] = v; if (++tail == buf.length) { tail = 0 ; } //插入一個方法,總量++ ++count; } /** * 取出一個數據 * @return */ protected synchronized final V doTake() { V v = buf[head]; buf[head] = null ; if (++head == buf.length) { head = 0 ; } --count; return v; } //通過對count的判斷,來確定數組是否是滿的 public synchronized final boolean isFull() { return count == buf.length; } public synchronized final boolean isEmpty() { return count == 0 ; } } |
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
30
31
32
33
34
35
36
37
38
39
40
41
|
package cn.xf.cp.ch14; /** * *功能:對插入和獲取元素操作進行先行檢查,然后執行操作,校驗不通過不予操作 *時間:下午2:33:41 *文件:GrumpyBoundedBuffer.java *@author Administrator * * @param <V> */ public class GrumpyBoundedBuffer<V> extends BaseBoundedBuffer<V> { public GrumpyBoundedBuffer( int size) { super (size); } public synchronized void put(V v) throws Exception { //如果是滿的隊列,就無法插入新的元素 if ( this .isFull()) { throw new Exception( "隊列超出" ); } this .doPut(v); } //同理,隊列為空的就無法取出新的元素 public synchronized V take() throws Exception { if ( this .isEmpty()) { throw new Exception( "隊列中無元素" ); } return this .doTake(); } } |
3、通過輪詢與休眠來實現簡單的阻塞
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
|
package cn.xf.cp.ch14; /** * *功能:通過輪詢與休眠來實現簡單的阻塞 *時間:下午2:55:54 *文件:SleepyBoundedBuffer.java *@author Administrator * * @param <V> */ public class SleepyBoundedBuffer<V> extends BaseBoundedBuffer<V> { //2s private static final long SLEEP_GRANULARITY = 2000 ; public SleepyBoundedBuffer( int capacity) { super (capacity); } //放入隊列的時候 public void put(V v) throws InterruptedException { while ( true ) { //這里不對循環上鎖,不然這個鎖就無法釋放了,不對休眠上鎖,休眠上鎖,在休眠的時候別人也無法操作,永遠都不可能有元素出去 synchronized ( this ) { //如果隊列不是滿的,那么就放入元素 if (! this .isFull()) { this .doPut(v); return ; } } //否則休眠,退出cpu占用 Thread.sleep(SLEEP_GRANULARITY); } } public V take() throws InterruptedException { while ( true ) { //這里不對循環上鎖,不然這個鎖就無法釋放了,不對休眠上鎖,休眠上鎖,在休眠的時候別人也無法操作,永遠都不可能有新的元素進來 synchronized ( this ) { //如果數組部位空,那么就可以取出數據 if (! this .isEmpty()) { return this .doTake(); } //如果隊列為空,休眠幾秒再試 } Thread.sleep(SLEEP_GRANULARITY); } } } |
4、條件隊列
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
|
package cn.xf.cp.ch14; /** * *功能:使用條件隊列 *時間:下午3:32:04 *文件:BoundedBuffer.java *@author Administrator * * @param <V> */ public class BoundedBuffer<V> extends BaseBoundedBuffer<V> { public BoundedBuffer( int capacity) { super (capacity); } /** * 放入數據元素 * @param v * @throws InterruptedException */ public synchronized void put(V v) throws InterruptedException { while ( this .isFull()) { //這里掛起程序,會釋放鎖 this .wait(); } //如果隊列不為滿的,那么程序被喚醒之后從新獲取鎖 this .doPut(v); //執行結束,喚醒其他隊列 this .notifyAll(); } public synchronized V take() throws InterruptedException { while ( this .isEmpty()) { this .wait(); } V v = this .doTake(); this .notifyAll(); return v; } } |
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!