<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    新的起點 新的開始

    快樂生活 !

    (轉)Java 5.0多線程編程(3)

    Lock 接口

    ReentrantLock Lock 的具體類, Lock 提供了以下一些方法:

    • lock(): 請求鎖定,如果鎖已被別的線程鎖定,調用此方法的線程被阻斷進入等待狀態。
    • tryLock() :如果鎖沒被別的線程鎖定,進入鎖定狀態,并返回 true 。若鎖已被鎖定,返回 false ,不進入等待狀態。此方法還可帶時間參數,如果鎖在方法執行時已被鎖定,線程將繼續等待規定的時間,若還不行才返回 false
    • unlock() :取消鎖定,需要注意的是 Lock 不會自動取消,編程時必須手動解鎖。

    代碼:

    // 生成一個鎖

    Lock lock = new ReentrantLock();

    public void accessProtectedResource() {

    ? lock.lock(); // 取得鎖定

    ? try {

    ??? // 對共享資源進行操作

    ? } finally {

    ??? // 一定記著把鎖取消掉,鎖本身是不會自動解鎖的

    ??? lock.unlock();

    ? }

    }

    ReadWriteLock 接口

    ?? 為了提高效率有些共享資源允許同時進行多個讀的操作,但只允許一個寫的操作,比如一個文件,只要其內容不變可以讓多個線程同時讀,不必做排他的鎖定,排他的鎖定只有在寫的時候需要,以保證別的線程不會看到數據不完整的文件。 ReadWriteLock 可滿足這種需要。 ReadWriteLock 內置兩個 Lock ,一個是讀的 Lock ,一個是寫的 Lock 。多個線程可同時得到讀的 Lock ,但只有一個線程能得到寫的 Lock ,而且寫的 Lock 被鎖定后,任何線程都不能得到 Lock ReadWriteLock 提供的方法有:

    • readLock(): 返回一個讀的 lock
    • writeLock(): 返回一個寫的 lock, lock 是排他的。

    ReadWriteLock 的例子:

    public class FileOperator{

    ????? // 初始化一個 ReadWriteLock

    ????? ReadWriteLock lock = new ReentrantReadWriteLock();

    public String read() {

    ????? // 得到 readLock 并鎖定

    ??????????? Lock readLock = lock.readLock();

    ?????? ?????readLock.lock();

    ??????????? try {

    ????????????????? // 做讀的工作

    ????????????????? return "Read something";

    ??????????? } finally {

    ???????????????? readLock.unlock();

    ??????????? }

    ????? }

    ?????

    public void write(String content) {

    ????? // 得到 writeLock 并鎖定

    ??????????? Lock writeLock = lock.writeLock();

    ??????????? writeLock.lock();

    ??????????? try {

    ????????????????? // 做讀的工作

    ??????????? } finally {

    ???????????????? writeLock.unlock();

    ??????????? }

    ????? }

    }

    ?

    ?? 需要注意的是 ReadWriteLock 提供了一個高效的鎖定機理,但最終程序的運行效率是和程序的設計息息相關的,比如說如果讀的線程和寫的線程同時在等待,要考慮是先發放讀的 lock 還是先發放寫的 lock 。如果寫發生的頻率不高,而且快,可以考慮先給寫的 lock 。還要考慮的問題是如果一個寫正在等待讀完成,此時一個新的讀進來,是否要給這個新的讀發鎖,如果發了,可能導致寫的線程等很久。等等此類問題在編程時都要給予充分的考慮。

    Condition 接口:

    ?? 有時候線程取得 lock 后需要在一定條件下才能做某些工作,比如說經典的 Producer Consumer 問題, Consumer 必須在籃子里有蘋果的時候才能吃蘋果,否則它必須暫時放棄對籃子的鎖定,等到 Producer 往籃子里放了蘋果后再去拿來吃。而 Producer 必須等到籃子空了才能往里放蘋果,否則它也需要暫時解鎖等 Consumer 把蘋果吃了才能往籃子里放蘋果。在 Java 5.0 以前,這種功能是由 Object 類的 wait(), notify() notifyAll() 等方法實現的,在 5.0 里面,這些功能集中到了 Condition 這個接口來實現, Condition 提供以下方法:

    • await() :使調用此方法的線程放棄鎖定,進入睡眠直到被打斷或被喚醒。
    • signal(): 喚醒一個等待的線程
    • signalAll() :喚醒所有等待的線程

    Condition 的例子:

    public class Basket {?????

    Lock lock = new ReentrantLock();

    // 產生 Condition 對象

    ???? Condition produced = lock.newCondition();

    ???? Condition consumed = lock.newCondition();

    ???? boolean available = false;

    ?? ??

    ???? public void produce() throws InterruptedException {

    ?????????? lock.lock();

    ?????????? try {

    ???????????????? if(available){

    ??????????????????? consumed.await(); // 放棄 lock 進入睡眠 ?

    ???????????????? }

    ???????????????? /* 生產蘋果 */

    ???????????????? System.out.println("Apple produced.");

    ???????????????? available = true;

    ???????????????? produced.signal(); // 發信號喚醒等待這個 Condition 的線程

    ?????????? } finally {

    ???????????????? lock.unlock();

    ?????????? }

    ???? }

    ????

    ???? public void consume() throws InterruptedException {

    ?????????? lock.lock();

    ?????????? try {

    ???????????????? if(!available){

    ?????????????????????? produced.await();// 放棄 lock 進入睡眠 ?

    ???????????????? }

    ???????????????? /* 吃蘋果 */

    ???????????????? System.out.println("Apple consumed.");

    ???????????????? available = false;

    ???????????????? consumed.signal();// 發信號喚醒等待這個 Condition 的線程

    ?????????? } finally {

    ???????????????? lock.unlock();

    ?????????? }

    ???? }?????

    }

    ConditionTester:

    public class ConditionTester {

    ?????

    ????? public static void main(String[] args) throws InterruptedException{

    final Basket basket = new Basket();

    // 定義一個 producer

    ??????????? Runnable producer = new Runnable() {

    ????????????????? public void run() {

    ??????????????????????? try {

    ????????????????????????????? basket.produce();

    ?????? ?????????????????} catch (InterruptedException ex) {

    ????????????????????????????? ex.printStackTrace();

    ??????????????????????? }

    ????????????????? }

    };

    // 定義一個 consumer

    ??????????? Runnable consumer = new Runnable() {

    ????????????????? public void run() {

    ??????????????????????? try {

    ????????????????????????????? basket.consume();

    ??????????????????????? } catch (InterruptedException ex) {

    ????????????????????????????? ex.printStackTrace();

    ??????????????????????? }

    ????????????????? }

    };

    // 各產生 10 consumer producer

    ??????????? ExecutorService service = Executors.newCachedThreadPool();

    ??????????? for(int i=0; i < 10; i++)

    ????????????????? service.submit(consumer);

    ??????????? Thread.sleep(2000);

    ??????????? for(int i=0; i<10; i++)

    ????????????????? service.submit(producer);

    ??????????? service.shutdown();

    ????? }?????

    }

    5: Synchronizer:同步裝置

    ?? Java 5.0 里新加了 4 個協調線程間進程的同步裝置,它們分別是 Semaphore, CountDownLatch, CyclicBarrier Exchanger.

    Semaphore:

    ?? 用來管理一個資源池的工具, Semaphore 可以看成是個通行證,線程要想從資源池拿到資源必須先拿到通行證, Semaphore 提供的通行證數量和資源池的大小一致。如果線程暫時拿不到通行證,線程就會被阻斷進入等待狀態。以下是一個例子:

    public class Pool {

    ??? ??ArrayList pool = null;

    ????? Semaphore pass = null;

    ????? public Pool(int size){

    ??????????? // 初始化資源池

    ??????????? pool = new ArrayList();

    ??????????? for(int i=0; i

    ????????????????? pool.add("Resource "+i);

    ??????????? }

    ??? ????????//Semaphore 的大小和資源池的大小一致

    ??????????? pass = new Semaphore(size);

    ????? }

    ????? public String get() throws InterruptedException{

    ??????????? // 獲取通行證 , 只有得到通行證后才能得到資源

    ??????????? pass.acquire();

    ??????????? return getResource();

    ????? }

    ????? public void put(String resource){

    ??????????? // 歸還通行證,并歸還資源

    ??????????? pass.release();

    ??????????? releaseResource(resource);

    ????? }

    ???? private synchronized String getResource() {

    ??????????? String result = pool.get(0);

    ??????????? pool.remove(0);

    ??????????? System.out.println("Give out "+result);

    ??????????? return result;

    ????? }

    ????? private synchronized void releaseResource(String resource) {

    ??????????? System.out.println("return "+resource);

    ??????????? pool.add(resource);

    ????? }

    }

    SemaphoreTest:

    public class SemaphoreTest {

    ????? public static void main(String[] args){

    ??????????? final Pool aPool = new Pool(2);

    ??????????? Runnable worker = new Runnable() {

    ????????????????? public void run() {

    ??????????????????????? String resource = null;

    ??????? ????????????????try {

    ????????????????????????????? // 取得 resource

    ????????????????????????????? resource = aPool.get();

    ??????????????????????? } catch (InterruptedException ex) {

    ????????????????????????????? ex.printStackTrace();

    ??????????????????????? }

    ??????????????????????? // resource 做工作

    ??????????????????????? System.out.println("I worked on "+resource);

    ??????????????????????? // 歸還 resource

    ??????????????????????? aPool.put(resource);

    ????????????????? }

    ??????????? };

    ??????????? ExecutorService service = Executors.newCachedThreadPool();

    ??????????? for(int i=0; i<20; i++){

    ????????????????? service.submit(worker);

    ??????????? }

    ??????????? service.shutdown();

    ????? }????

    }


    posted on 2007-03-26 14:31 advincenting 閱讀(256) 評論(0)  編輯  收藏


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     

    公告

    Locations of visitors to this pageBlogJava
  • 首頁
  • 新隨筆
  • 聯系
  • 聚合
  • 管理
  • <2007年3月>
    25262728123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    統計

    常用鏈接

    留言簿(13)

    隨筆分類(71)

    隨筆檔案(179)

    文章檔案(13)

    新聞分類

    IT人的英語學習網站

    JAVA站點

    優秀個人博客鏈接

    官網學習站點

    生活工作站點

    最新隨筆

    搜索

    積分與排名

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 最新中文字幕免费视频| 最近2019免费中文字幕6| 国产男女猛烈无遮挡免费视频网站 | 99在线热播精品免费99热| 亚洲精品国产高清嫩草影院| 国产亚洲视频在线| xvideos亚洲永久网址| 无忧传媒视频免费观看入口| 国产免费av一区二区三区| 国产成人亚洲精品91专区高清| 日韩免费电影在线观看| 国产精品亚洲专区一区| 亚洲国产成人乱码精品女人久久久不卡 | 亚洲爆乳AAA无码专区| 久草在视频免费福利| 亚洲国产综合在线| 毛片a级毛片免费观看免下载 | 国产亚洲福利精品一区| 98精品全国免费观看视频| 亚洲午夜电影在线观看| 免费看a级黄色片| 一级女性全黄生活片免费看| 91麻豆国产自产在线观看亚洲 | 久久99精品免费一区二区| 亚洲线精品一区二区三区影音先锋| 免费精品一区二区三区第35 | 成人免费福利视频| 亚洲日本VA午夜在线电影| 又粗又硬免费毛片| 国内精品99亚洲免费高清| 中文字幕在线观看亚洲| 午夜视频免费成人| 久久久久久av无码免费看大片| 亚洲伦理一区二区| 在线a人片天堂免费观看高清| www.av在线免费观看| 亚洲男人都懂得羞羞网站| 全免费a级毛片免费看不卡| 在线播放免费人成视频网站| 亚洲高清在线mv| 免费人成在线观看视频播放|