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接口在指定的截止时间之前获取锁,如果截止时间到了依旧无法获取锁,则返回。

猜你喜欢

转载自blog.csdn.net/www1056481167/article/details/104507237
今日推荐