Lock锁实现生产者消费者及Condition 精准的通知和唤醒线程
Synchronized实现时用wait()方法等待和notify()唤醒。
Lock锁用的是Condtion对象的await()方法等待和signal()唤醒。
Lock锁实现生产者消费者问题
public class ProAndConByLock1 {
public static void main(String[] args) {
Data1 data1 = new Data1();
/* ()->{}: lambda表达式 (参数)->{ 代码 } 就是下面的:
new Runnable() {
@Override
public void run() {}
*/
new Thread(()->{ for (int i = 0; i < 5; i++) data1.increment();},"Pro").start(); // 生产者线程
new Thread(()->{ for (int i = 0; i < 5; i++) data1.decrement();},"Con").start(); // 消费者线程
}
}
// 资源类
class Data1{
private int num=0;
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void increment(){ // 生产+1
// 加锁
lock.lock();
try {
while (num!=0){
condition.await(); // 等待
}
num++;
System.out.println(Thread.currentThread().getName()+"执行了; num="+num);
// 唤醒所有等待的线程
condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock(); // 解锁
}
}
public void decrement(){ // 消费-1
// 加锁
lock.lock();
try {
while (num!=1){
condition.await(); // 等待
}
num--;
System.out.println(Thread.currentThread().getName()+"执行了; num="+num);
// 唤醒所有等待的线程
condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock(); // 解锁
}
}
}
Condition 精准的通知和唤醒线程
要求线程执行顺序 : A线程执行 --> B线程执行 --> C线程执行
public class ProAndConByLock {
public static void main(String[] args) {
Data data = new Data();
/* ()->{}: lambda表达式 (参数)->{ 代码 } 就是下面的:
new Runnable() {
@Override
public void run() {}
*/
// 要求线程执行顺序 : A线程执行 --> B线程执行 --> C线程执行
new Thread(()->{ for (int i = 0; i < 5; i++) data.a(); },"A").start();
new Thread(()->{ for (int i = 0; i < 5; i++) data.b(); },"B").start();
new Thread(()->{ for (int i = 0; i < 5; i++) data.c(); },"C").start();
}
}
// 资源类
class Data{
private int num=1; // num=1 唤醒A线程 ,num=2 唤醒B线程 ,num=3 唤醒C线程
private Lock lock = new ReentrantLock();
// 如果A线程condition1.await(); 等待 。 那么 condition1.signal(); 唤醒的就是指定的A线程
private Condition condition1 = lock.newCondition();
private Condition condition2 = lock.newCondition();
private Condition condition3 = lock.newCondition();
public void a(){
// 加锁
lock.lock();
try {
while (num!=1){ // while判断防止虚假唤醒
condition1.await(); // 等待
}
System.out.println(Thread.currentThread().getName()+"执行了; num="+num);
num=2;
// 唤醒
condition2.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock(); // 解锁
}
}
public void b(){
// 加锁
lock.lock();
try {
while (num!=2){
condition2.await(); // 等待
}
System.out.println(Thread.currentThread().getName()+"执行了; num="+num);
num=3;
// 唤醒
condition3.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock(); // 解锁
}
}
public void c(){
// 加锁
lock.lock();
try {
while (num!=3){
condition3.await(); // 等待
}
System.out.println(Thread.currentThread().getName()+"执行了; num="+num);
num=1;
// 唤醒
condition1.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock(); // 解锁
}
}
}
结果:按照 A线程 --> B线程 --> C线程 顺序执行