版权声明:本文为博主原创文章,允许转载,请标明出处。 https://blog.csdn.net/qwdafedv/article/details/84113115
类似于上一篇使用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()类似,
只不过在未获取到锁时,设置了一个等待时间来尝试再次拿锁。