Java並發程式設計(15)並發鎖之讀寫鎖(續二)寫鎖降級

來源:互聯網
上載者:User

標籤:依次   back   pos   share   1.5   called   exe   nal   this   

 

1.1.1. 讀寫鎖應用之三寫鎖降級

 

ReentrantReadWriteLock還具有寫鎖降級的特點,而這跟可重新進入性有一些關係。

(1)持有寫鎖時可以降級為讀鎖。

(2)持有讀鎖時不能升級為寫鎖。

 

 

ReentrantReadWriteLock和ReentrantLock相似的是都有一個特點,就是可重新進入。可重新進入指已經擷取到鎖的線程可以再次擷取鎖,保證lock和unlock的次數相同即可。

package com.test.concurrence; import java.util.Random;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.locks.ReadWriteLock;import java.util.concurrent.locks.ReentrantReadWriteLock;  class  MySharedResource3 {  //建構函式:公平鎖。private ReadWriteLock  lock = new ReentrantReadWriteLock(true); public void  read(int taskid){lock.readLock().lock();try{for(int i=0;i<10;i++){x--;System.out.println(taskid + "," + i + ": read called: x:" + x + " , "+ Thread.currentThread().getName());Thread.sleep(100);}} catch (InterruptedException e) {e.printStackTrace();}finally{lock.readLock().unlock();}}  public void  downgrade(int taskid){//持有寫鎖lock.writeLock().lock();System.out.println(taskid + " writeLock locked."); try{    for(int i=0;i<10;i++){x++;System.out.println(taskid + "," + i  + ": write called: x:" + x + " , "+ Thread.currentThread().getName());Thread.sleep(100);}     //在已經持有寫鎖的情況下繼續持有讀鎖。lock.readLock().lock();System.out.println(taskid + " writeLock ->  readLock locked."); //釋放寫鎖後,降級為讀鎖。lock.writeLock().unlock();System.out.println(taskid + " writeLock unlocked.");  for(int i=0;i<10;i++){x++;System.out.println(taskid + "," + i  + ": read in write: x:" + x + " , "+ Thread.currentThread().getName());Thread.sleep(1000);} //釋放讀鎖。lock.readLock().unlock();    System.out.println(taskid + " readLock locked.");  } catch (InterruptedException e) {e.printStackTrace();}finally{//釋放鎖。lock.readLock().lock();lock.writeLock().unlock();}}  private   int  x = 0;}  public class ReadWriteLockTest3 {public static void main(String[] args) {final MySharedResource3  sr = new MySharedResource3();ExecutorService  executorService =  Executors.newCachedThreadPool();int i; for( i=0;i<10;i++) {final int taskid = i;executorService.execute(new Runnable(){@Overridepublic void run() {System.out.println("taskid:" + taskid);while(true){if( 0 == (taskid % 2)){sr.downgrade(taskid);}else {sr.read(taskid);}}}});}executorService.shutdown();}} 

 

 

觀察運行結果,可以看到在downgrade()函數中,當線程在執行寫鎖已經降級為讀鎖後的代碼塊時,其它線程時可以獲得讀鎖的。

 

一個可能的運行結果如下:

 

taskid:0

taskid:4

taskid:3

taskid:1

taskid:2

0 writeLock locked.

taskid:5

0,0: write called: x:1 , pool-1-thread-1

taskid:6

taskid:9

taskid:8

taskid:7

0,1: write called: x:2 , pool-1-thread-1

0,2: write called: x:3 , pool-1-thread-1

0,3: write called: x:4 , pool-1-thread-1

0,4: write called: x:5 , pool-1-thread-1

0,5: write called: x:6 , pool-1-thread-1

0,6: write called: x:7 , pool-1-thread-1

0,7: write called: x:8 , pool-1-thread-1

0,8: write called: x:9 , pool-1-thread-1

0,9: write called: x:10 , pool-1-thread-1

0 writeLock ->  readLock locked.

0 writeLock unlocked.

0,0: read in write: x:11 , pool-1-thread-1

3,0: read called: x:10 , pool-1-thread-4

3,1: read called: x:9 , pool-1-thread-4

3,2: read called: x:8 , pool-1-thread-4

3,3: read called: x:7 , pool-1-thread-4

3,4: read called: x:6 , pool-1-thread-4

3,5: read called: x:5 , pool-1-thread-4

3,6: read called: x:4 , pool-1-thread-4

3,7: read called: x:3 , pool-1-thread-4

3,8: read called: x:2 , pool-1-thread-4

3,9: read called: x:1 , pool-1-thread-4

0,1: read in write: x:2 , pool-1-thread-1

0,2: read in write: x:3 , pool-1-thread-1

0,3: read in write: x:4 , pool-1-thread-1

0,4: read in write: x:5 , pool-1-thread-1

0,5: read in write: x:6 , pool-1-thread-1

0,6: read in write: x:7 , pool-1-thread-1

0,7: read in write: x:8 , pool-1-thread-1

0,8: read in write: x:9 , pool-1-thread-1

0,9: read in write: x:10 , pool-1-thread-1

0 readLock locked.

4 writeLock locked.

4,0: write called: x:11 , pool-1-thread-5

4,1: write called: x:12 , pool-1-thread-5

4,2: write called: x:13 , pool-1-thread-5

4,3: write called: x:14 , pool-1-thread-5

4,4: write called: x:15 , pool-1-thread-5

4,5: write called: x:16 , pool-1-thread-5

4,6: write called: x:17 , pool-1-thread-5

4,7: write called: x:18 , pool-1-thread-5

4,8: write called: x:19 , pool-1-thread-5

4,9: write called: x:20 , pool-1-thread-5

4 writeLock ->  readLock locked.

4 writeLock unlocked.

1,0: read called: x:19 , pool-1-thread-2

4,0: read in write: x:20 , pool-1-thread-5

1,1: read called: x:19 , pool-1-thread-2

1,2: read called: x:18 , pool-1-thread-2

1,3: read called: x:17 , pool-1-thread-2

1,4: read called: x:16 , pool-1-thread-2

1,5: read called: x:15 , pool-1-thread-2

1,6: read called: x:14 , pool-1-thread-2

1,7: read called: x:13 , pool-1-thread-2

1,8: read called: x:12 , pool-1-thread-2

1,9: read called: x:11 , pool-1-thread-2

4,1: read in write: x:12 , pool-1-thread-5

4,2: read in write: x:13 , pool-1-thread-5

4,3: read in write: x:14 , pool-1-thread-5

4,4: read in write: x:15 , pool-1-thread-5

4,5: read in write: x:16 , pool-1-thread-5

4,6: read in write: x:17 , pool-1-thread-5

4,7: read in write: x:18 , pool-1-thread-5

4,8: read in write: x:19 , pool-1-thread-5

4,9: read in write: x:20 , pool-1-thread-5

4 readLock locked.

2 writeLock locked.

2,0: write called: x:21 , pool-1-thread-3

2,1: write called: x:22 , pool-1-thread-3

2,2: write called: x:23 , pool-1-thread-3

2,3: write called: x:24 , pool-1-thread-3

2,4: write called: x:25 , pool-1-thread-3

2,5: write called: x:26 , pool-1-thread-3

2,6: write called: x:27 , pool-1-thread-3

2,7: write called: x:28 , pool-1-thread-3

2,8: write called: x:29 , pool-1-thread-3

2,9: write called: x:30 , pool-1-thread-3

2 writeLock ->  readLock locked.

2 writeLock unlocked.

5,0: read called: x:29 , pool-1-thread-6

2,0: read in write: x:30 , pool-1-thread-3

5,1: read called: x:29 , pool-1-thread-6

5,2: read called: x:28 , pool-1-thread-6

5,3: read called: x:27 , pool-1-thread-6

5,4: read called: x:26 , pool-1-thread-6

5,5: read called: x:25 , pool-1-thread-6

5,6: read called: x:24 , pool-1-thread-6

5,7: read called: x:23 , pool-1-thread-6

5,8: read called: x:22 , pool-1-thread-6

5,9: read called: x:21 , pool-1-thread-6

2,1: read in write: x:22 , pool-1-thread-3

2,2: read in write: x:23 , pool-1-thread-3

2,3: read in write: x:24 , pool-1-thread-3

2,4: read in write: x:25 , pool-1-thread-3

2,5: read in write: x:26 , pool-1-thread-3

2,6: read in write: x:27 , pool-1-thread-3

2,7: read in write: x:28 , pool-1-thread-3

2,8: read in write: x:29 , pool-1-thread-3

2,9: read in write: x:30 , pool-1-thread-3

2 readLock locked.

6 writeLock locked.

6,0: write called: x:31 , pool-1-thread-7

6,1: write called: x:32 , pool-1-thread-7

6,2: write called: x:33 , pool-1-thread-7

6,3: write called: x:34 , pool-1-thread-7

6,4: write called: x:35 , pool-1-thread-7

6,5: write called: x:36 , pool-1-thread-7

6,6: write called: x:37 , pool-1-thread-7

6,7: write called: x:38 , pool-1-thread-7

6,8: write called: x:39 , pool-1-thread-7

6,9: write called: x:40 , pool-1-thread-7

6 writeLock ->  readLock locked.

6 writeLock unlocked.

6,0: read in write: x:41 , pool-1-thread-7

9,0: read called: x:40 , pool-1-thread-10

9,1: read called: x:39 , pool-1-thread-10

9,2: read called: x:38 , pool-1-thread-10

9,3: read called: x:37 , pool-1-thread-10

9,4: read called: x:36 , pool-1-thread-10

9,5: read called: x:35 , pool-1-thread-10

9,6: read called: x:34 , pool-1-thread-10

9,7: read called: x:33 , pool-1-thread-10

9,8: read called: x:32 , pool-1-thread-10

9,9: read called: x:31 , pool-1-thread-10

6,1: read in write: x:32 , pool-1-thread-7

6,2: read in write: x:33 , pool-1-thread-7

6,3: read in write: x:34 , pool-1-thread-7

6,4: read in write: x:35 , pool-1-thread-7

6,5: read in write: x:36 , pool-1-thread-7

 

 

api doc中關於可重新進入和降級是這麼的。

 

Reentrancy

This lock allows both readers and writers to reacquire read or write locks in the style of a ReentrantLock. Non-reentrant readers are not allowed until all write locks held by the writing thread have been released.

 

Additionally, a writer can acquire the read lock, but not vice-versa. Among other applications, reentrancy can be useful when write locks are held during calls or callbacks to methods that perform reads under read locks. If a reader tries to acquire the write lock it will never succeed.

【中文】

可重新進入性

這種鎖(ReentrantReadWriteLock)允許讀線程和寫線程按照ReentrantLock的式樣來再次擷取到讀或寫鎖。非重入的讀是不允許的,直到所有已經被寫線程持有的寫鎖都被 釋放了。

另外,寫線程能夠擷取到讀鎖,但是反過來不行。在其他應用中,調用或回調方法中需要持有讀鎖時執行讀操作時,在已經持有寫鎖的情況下,可重新進入性是有用的。如果讀線程嘗試擷取寫鎖,將不會成功。

 

 

Lock downgrading

Reentrancy also allows downgrading from the write lock to a read lock, by acquiring the write lock, then the read lock and then releasing the write lock. However, upgrading from a read lock to the write lock is not possible.

【中文】

鎖降級

通過依次擷取寫鎖,擷取讀鎖,然後釋放寫鎖的方式,可重新進入性也允許從一個寫鎖降級為一個讀鎖。然而,從一個讀鎖定擴大到寫鎖是不可能的。

 

Java並發程式設計(15)並發鎖之讀寫鎖(續二)寫鎖降級

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.