011.多线程-lock锁

类似于上一篇使用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()类似,
只不过在未获取到锁时,设置了一个等待时间来尝试再次拿锁。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值