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

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

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

    新的起點(diǎn) 新的開始

    快樂生活 !

    (轉(zhuǎn))Java 5.0多線程編程(3)

    Lock 接口

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

    • lock(): 請(qǐng)求鎖定,如果鎖已被別的線程鎖定,調(diào)用此方法的線程被阻斷進(jìn)入等待狀態(tài)。
    • tryLock() :如果鎖沒被別的線程鎖定,進(jìn)入鎖定狀態(tài),并返回 true 。若鎖已被鎖定,返回 false ,不進(jìn)入等待狀態(tài)。此方法還可帶時(shí)間參數(shù),如果鎖在方法執(zhí)行時(shí)已被鎖定,線程將繼續(xù)等待規(guī)定的時(shí)間,若還不行才返回 false
    • unlock() :取消鎖定,需要注意的是 Lock 不會(huì)自動(dòng)取消,編程時(shí)必須手動(dòng)解鎖。

    代碼:

    // 生成一個(gè)鎖

    Lock lock = new ReentrantLock();

    public void accessProtectedResource() {

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

    ? try {

    ??? // 對(duì)共享資源進(jìn)行操作

    ? } finally {

    ??? // 一定記著把鎖取消掉,鎖本身是不會(huì)自動(dòng)解鎖的

    ??? lock.unlock();

    ? }

    }

    ReadWriteLock 接口

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

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

    ReadWriteLock 的例子:

    public class FileOperator{

    ????? // 初始化一個(gè) 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 提供了一個(gè)高效的鎖定機(jī)理,但最終程序的運(yùn)行效率是和程序的設(shè)計(jì)息息相關(guān)的,比如說如果讀的線程和寫的線程同時(shí)在等待,要考慮是先發(fā)放讀的 lock 還是先發(fā)放寫的 lock 。如果寫發(fā)生的頻率不高,而且快,可以考慮先給寫的 lock 。還要考慮的問題是如果一個(gè)寫正在等待讀完成,此時(shí)一個(gè)新的讀進(jìn)來,是否要給這個(gè)新的讀發(fā)鎖,如果發(fā)了,可能導(dǎo)致寫的線程等很久。等等此類問題在編程時(shí)都要給予充分的考慮。

    Condition 接口:

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

    • await() :使調(diào)用此方法的線程放棄鎖定,進(jìn)入睡眠直到被打斷或被喚醒。
    • signal(): 喚醒一個(gè)等待的線程
    • signalAll() :?jiǎn)拘阉械却木€程

    Condition 的例子:

    public class Basket {?????

    Lock lock = new ReentrantLock();

    // 產(chǎn)生 Condition 對(duì)象

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

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

    ???? boolean available = false;

    ?? ??

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

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

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

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

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

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

    ???????????????? /* 生產(chǎn)蘋果 */

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

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

    ???????????????? produced.signal(); // 發(fā)信號(hào)喚醒等待這個(gè) Condition 的線程

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

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

    ?????????? }

    ???? }

    ????

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

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

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

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

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

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

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

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

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

    ???????????????? consumed.signal();// 發(fā)信號(hào)喚醒等待這個(gè) Condition 的線程

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

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

    ?????????? }

    ???? }?????

    }

    ConditionTester:

    public class ConditionTester {

    ?????

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

    final Basket basket = new Basket();

    // 定義一個(gè) producer

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

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

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

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

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

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

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

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

    };

    // 定義一個(gè) consumer

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

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

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

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

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

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

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

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

    };

    // 各產(chǎn)生 10 個(gè) 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 個(gè)協(xié)調(diào)線程間進(jìn)程的同步裝置,它們分別是 Semaphore, CountDownLatch, CyclicBarrier Exchanger.

    Semaphore:

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

    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) 評(píng)論(0)  編輯  收藏


    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     

    公告

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

    統(tǒng)計(jì)

    常用鏈接

    留言簿(13)

    隨筆分類(71)

    隨筆檔案(179)

    文章檔案(13)

    新聞分類

    IT人的英語學(xué)習(xí)網(wǎng)站

    JAVA站點(diǎn)

    優(yōu)秀個(gè)人博客鏈接

    官網(wǎng)學(xué)習(xí)站點(diǎn)

    生活工作站點(diǎn)

    最新隨筆

    搜索

    積分與排名

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 九九免费观看全部免费视频| 亚洲理论片在线中文字幕| 俄罗斯极品美女毛片免费播放| 精品国产免费观看一区| 大香人蕉免费视频75| 热99re久久精品精品免费| 日本不卡免费新一二三区| 免费国产成人午夜私人影视 | 两个人日本免费完整版在线观看1| 深夜福利在线视频免费| 亚洲天堂免费在线视频| 一个人看的www免费视频在线观看| 在线播放免费人成毛片乱码| 一级毛片在线免费看| 无码av免费毛片一区二区| 欧美男同gv免费网站观看| 午夜老司机免费视频| 亚洲AV伊人久久青青草原| 国产精品亚洲不卡一区二区三区 | 在线观看无码AV网站永久免费| 久久笫一福利免费导航| 在线免费一区二区| 免费va在线观看| 亚洲人成亚洲人成在线观看| 亚洲成在人天堂在线| 亚洲伊人久久大香线蕉| 亚洲aⅴ无码专区在线观看| 一级毛片免费在线观看网站| 久久国产乱子精品免费女| av免费不卡国产观看| 国产色爽免费视频| 亚洲无人区一区二区三区| 亚洲高清视频免费| 亚洲国产午夜精品理论片在线播放 | 亚洲人成影院午夜网站| 亚洲成av人片在线天堂无| eeuss草民免费| h视频在线免费看| 国产男女猛烈无遮挡免费视频| 亚洲精品国产成人片| 亚洲一区电影在线观看|