前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >011.多线程-lock锁

011.多线程-lock锁

作者头像
qubianzhong
发布2018-12-13 16:57:36
3630
发布2018-12-13 16:57:36
举报
文章被收录于专栏:行者常至行者常至行者常至

版权声明:本文为博主原创文章,允许转载,请标明出处。

类似于上一篇使用synchronized实现生产者与消费者间的通信, 这里使用lock锁来实现。

package cn.qbz.thread;

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

/**
 * @Author: 花生米
 * @Date: 2018/11/15 22:04
 */
public class LockTest {

    public static void main(String[] args) {
        Student student = new Student();
        Lock lock = new ReentrantLock();
        Condition produceCondition = lock.newCondition();
        Condition consumerCondition = lock.newCondition();

        ProduceTest produceTest = new ProduceTest(student, lock, produceCondition, consumerCondition);
        ConsumerTest consumerTest = new ConsumerTest(student, lock, produceCondition, consumerCondition);

        produceTest.start();
        consumerTest.start();
    }
}

class ProduceTest extends Thread {
    private Student student;
    private Lock lock;
    private Condition produceCondition;
    private Condition consumerCondition;

    public ProduceTest(Student student, Lock lock,
                       Condition produceCondition,
                       Condition consumerCondition) {
        this.student = student;
        this.lock = lock;
        this.produceCondition = produceCondition;
        this.consumerCondition = consumerCondition;
    }

    @Override
    public void run() {
        int num = 1;
        while (true) {
            lock.lock();
            try {
                //如果可以生产,生产者生产
                if (student.getCanProduce()) {
                    if (num == 1) {
                        student.setAge(6);
                        student.setName("小王");
                        num = 0;
                    } else {
                        student.setName("老王");
                        student.setAge(99);
                        num = 1;
                    }

                    //重置生产者不可以生产
                    student.setCanProduce(false);
                }

                consumerCondition.signalAll();

                produceCondition.await();

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }

        }
    }
}

class ConsumerTest extends Thread {
    private Student student;
    private Lock lock;
    private Condition produceCondition;
    private Condition consumerCondition;

    public ConsumerTest(Student student, Lock lock, Condition produceCondition, Condition consumerCondition) {
        this.student = student;
        this.lock = lock;
        this.produceCondition = produceCondition;
        this.consumerCondition = consumerCondition;
    }

    @Override
    public void run() {
        while (true) {
            lock.lock();
            try {
                //如果不可以生产,进行消费
                if (!student.getCanProduce()) {
                    //重置生产者可以生产
                    student.setCanProduce(true);
                    System.out.println(student.toString());
                }

                produceCondition.signalAll();
                consumerCondition.await();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }

        }
    }
}

class Student {
    private String name;
    private Integer age;
    private Boolean canProduce = true;

    public Boolean getCanProduce() {
        return canProduce;
    }

    public void setCanProduce(Boolean canProduce) {
        this.canProduce = canProduce;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

lock中常用方法:

lock()、unlock()

	Lock lock = new ReentrantLock();
	lock.lock();
	try{
	//可能会出现线程安全的操作
	}finally{
	//一定在finally中释放锁
	//也不能把获取锁在try中进行,因为有可能在获取锁的时候抛出异常
	  lock.unlock();
	}

await()、signal()、signalAll()

	Lock lock = new ReentrantLock();
	Condition produceCondition = lock.newCondition();
	Condition consumerCondition = lock.newCondition();

	consumerCondition.signalAll();
	produceCondition.await();

lock中的await方法类似于synchronized的wait, signal、signalAll类似于notify、notifyAll。

需要注意: 虽然多个线程使用同一把lock锁, 但是每个线程的condition都是唯一的, 使用时需要注意。


trylock() 其功能与 lock() 一样,不过会有返回值, true:获取到lock锁;false:未获取lock锁。

   if (lock.tryLock()) {
        try {
            //如果不可以生产,进行消费
            if (!student.getCanProduce()) {
                //重置生产者可以生产
                student.setCanProduce(true);
                System.out.println(student.toString());
            }

            produceCondition.signalAll();
            consumerCondition.await();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

tryLock(long time, TimeUnit unit) 与tryLock()类似, 只不过在未获取到锁时,设置了一个等待时间来尝试再次拿锁。


本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年11月16日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档