jdk1.5-Lock的使用

package com.study.communication;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class LockRes {
    public String userName;
    public String sex;
    //true生產者線程等待,false消費者線程生產,生產者可以寫,消費者變爲等待
    public boolean flag = false;
    Lock lock = new ReentrantLock();//jdk1.5併發包lock鎖
}

/**
 * 讀
 */
@SuppressWarnings("Duplicates")
class LockOut extends Thread {
    LockRes lockRes;
    Condition newCondition;

    LockOut(LockRes lockRes, Condition newCondition) {
        this.lockRes = lockRes;
        this.newCondition = newCondition;
    }

    @Override
    public void run() {
        int count = 0;
        while (true) {
            try {
                lockRes.lock.lock();//表示開始上鎖
                if (lockRes.flag) {
                    try {
                        //讓線程等待
                        newCondition.await();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                if (count == 0) {
                    lockRes.userName = "小紅";
                    lockRes.sex = "女";
                } else {
                    lockRes.userName = "小王";
                    lockRes.sex = "男";
                }
                count = (count + 1) % 2;
                lockRes.flag = true;
                newCondition.signal();//喚醒
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lockRes.lock.unlock();
            }

        }
    }
}

/**
 * 寫
 */

class LockInput extends Thread {
    LockRes lockRes;
    Condition newCondition;

    LockInput(LockRes res, Condition newCondition) {
        this.lockRes = res;
        this.newCondition = newCondition;
    }

    @Override
    public void run() {
        while (true) {
            try {
                //此處,切勿重新new condition,因爲生產者和消費者必須要用通一把鎖資源,如果重新new的話,則不同了,所以此處需要注意
                //Condition newCondition=lockRes.lock.newCondition();
                lockRes.lock.lock();
                if (!lockRes.flag) {
                    try {
                        newCondition.await();//線程等待
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(lockRes.userName + "," + lockRes.sex);
                newCondition.signal();//喚醒
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lockRes.lock.unlock();
            }
        }
    }
}

public class LockThread {
    public static void main(String[] args) {
        LockRes res = new LockRes();
        Condition condition = res.lock.newCondition();
        //寫的線程
        LockOut out = new LockOut(res, condition);
        //讀的線程
        LockInput input = new LockInput(res, condition);
        out.start();
        input.start();
    }
}

特別注意點是newCondition.await();方法的使用,不能用成是wait方法。

Lock接口與synchroinzed關鍵字的區別
    1、Lock接口可以嘗試非阻塞的獲取鎖,當線程嘗試獲取鎖,如果這一時刻鎖沒有被其他線程獲取到,則成功獲取並持有鎖。
    2、Lock接口能被中斷的獲取鎖,與synchronized不同,獲取到的鎖的線程能夠響應中斷,當獲取到的鎖的線程被中斷時,中斷異常將會被拋出,同時鎖會被釋放。
    3、Lock接口在指定的截止時間之前獲取鎖,如果截止時間到了依舊無法獲取鎖,則返回。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章