細(xì)心!用心!耐心!

          吾非文人,乃市井一俗人也,讀百卷書,跨江河千里,故申城一游; 一兩滴辛酸,三四年學(xué)業(yè),五六點(diǎn)粗墨,七八筆買賣,九十道人情。

          BlogJava 聯(lián)系 聚合 管理
            1 Posts :: 196 Stories :: 10 Comments :: 0 Trackbacks
          如果有一個(gè)資料檔有可能同時(shí)間會(huì)有許多客戶端對(duì)它進(jìn)行讀取與寫入的動(dòng)作,則必須注意資料的同步問題,像是兩個(gè)寫入者進(jìn)行寫入時(shí),後一個(gè)寫入者的資料會(huì)有可能將次一個(gè)寫入者的資料覆蓋掉;而有時(shí)您希望讀取者看到的是最新的資料,如果在讀取的時(shí)候,有寫入者想要對(duì)資料進(jìn)行寫入,則最好等待讀取者讀取完畢,相反的如果在寫入時(shí)有客戶想要讀取資料,則最好等待,以確保讀出來的資料是最新的資料。

          讀取寫入的同步問題向來是難解的問題之一,有幾個(gè)可行的作法,例如若有寫入的動(dòng)作時(shí),則讀取者以唯讀模式開啟;或是如果有開啟資料檔的動(dòng)作時(shí),無論是讀取或是寫入,後一個(gè)開啟檔案的客戶都一律以唯讀模式開啟;還有最乾脆的作法,就是將這個(gè)問題由客戶決定,在開啟檔案時(shí)若已有其他人開啟中,則提供選項(xiàng)讓客戶決定要不要以唯讀模式開啟,通常這個(gè)作法是提供給檔案的擁有者使用。

          Read-Write-Lock 模式提供給被讀取或?qū)懭氲馁Y料「一把鎖」,在讀取或?qū)懭霑r(shí)都必須先取得這把鎖,讀取的客戶可以同時(shí)共同這把鎖,而寫入的客戶也可以共用這把鎖,但讀取不可與寫入共用一把鎖,如果嘗試取得鎖時(shí)發(fā)現(xiàn)鎖已經(jīng)被另一方取得,則等待直到鎖被釋放並重新取得它。

          下圖讀取者讀取資料時(shí)的Sequence Diagram示例:
          Read-Write-Lock

          現(xiàn)在假設(shè)讀取者已經(jīng)取得鎖,而寫入者試圖進(jìn)行寫入,它也試圖先取得鎖定,但發(fā)現(xiàn)鎖已經(jīng)被讀取的一方擁有,於是先進(jìn)入等待,直到讀取的一方解除鎖定為止:
          Read-Write-Lock

          一個(gè)簡(jiǎn)單的Java程式例子如下所示:
           public void readData() {
              lock.readLock();
              doRead();
              lock.readUnLock();
           }

           public void writeData() {
              lock.writeLock();
              doWrite();
              lock.writeUnLock();
           }
           

          而最主要的關(guān)鍵還是在於鎖的實(shí)現(xiàn),在Java中可以用wait()、notify()來實(shí)現(xiàn),實(shí)現(xiàn)的片段如下:
           private boolean writerFirst = true; // 寫入優(yōu)先
           
           public synchronized void readLock() {
              try {
                  while(writingWriters > 0 ||
                             (writerFirst && waitingWriters > 0)) {
                      wait();
                  }
              }
              catch(InterruptedException) {
              }

              readingReaders++;
           }
           
           public synchronized void readUnLock() {
              readingReaders--;
              writerFirst = true;
              notifyAll();
           }
           
           public synchronized void writeLock() {
              waitingWriters++
              try {
                  while(readingReaders > 0 || writingWriters > 0) {
                      wait();
                  }
              }
              catch(InterruptedException) {
              }
              finally {
                  waitingWriters--;
              }

              writingWriters++;
           }
           
           public synchronized void writeUnLock() {
              writingWriters--;
              writerFirst = false;
              notifyAll();
           }
           

          其中writerFirst是寫入優(yōu)先的旗標(biāo),它確保只要有寫入的執(zhí)行緒在等待時(shí),在解除鎖定的時(shí)候,可以優(yōu)先由寫入執(zhí)行緒取得鎖定,以確保讀取者讀取到的資料可以是最新的,但缺點(diǎn)就是寫入的動(dòng)作很頻繁時(shí),讀取者必須等待的機(jī)會(huì)將增多,相反的若設(shè)定為讀取優(yōu)先,則讀取時(shí)的回應(yīng)性會(huì)增高,但資料更新的速率將會(huì)下降,實(shí)際使用時(shí)要偏好哪一方,必須視應(yīng)用的場(chǎng)合而定。
          posted on 2007-04-17 10:58 張金鵬 閱讀(369) 評(píng)論(0)  編輯  收藏 所屬分類: 多執(zhí)行緒模式
          主站蜘蛛池模板: 株洲县| 巩留县| 正蓝旗| 岳普湖县| 边坝县| 合作市| 梁河县| 湘潭县| 顺平县| 绥芬河市| 长宁区| 乌鲁木齐市| 北票市| 普格县| 黄冈市| 威信县| 拜泉县| 雅江县| 哈巴河县| 定结县| 石嘴山市| 滨海县| 嘉祥县| 离岛区| 陵川县| 新巴尔虎左旗| 华亭县| 石楼县| 伊金霍洛旗| 苍山县| 武城县| 青田县| 沂源县| 南城县| 抚松县| 陆良县| 嵊泗县| 瑞丽市| 开化县| 博湖县| 英山县|