生产者消费者循环调用
本篇文章需要有一定的java多线程的基础。如果没有,建议先学习。
基础的生产者消费者相信大家都耳熟能详,生产者消费者无非就是利用java的锁机制,如果没有生产,那么久等待生产,生产好了就通知消费者来消费。还没消费那么久等待,消费完了那么就通知生产者生产。
常规的实现方式有两种,可以用到synchronized关键字实现,也可以用到lock锁实现。
我们今天的关键不是生产者消费者模式,而是一个和生产者消费者模式非常类似的循环调用模式。
要求如果数量为1的话就调用线程A,如果为2的话就调用线程B,如果为3的话就调用线程3。
我们采用的实现方式是juc的lock锁进行实现,由于lock里面有个Condition类可以用来指定唤醒相应的线程,实现这个再合适不过了。
具体实现如下:
public class aaa {
public static void main(String[] args) {
ticket ticket = new ticket();
new Thread(() -> {
for (int i = 1; i<= 10; i++) {
try {
ticket.one();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"A").start();
new Thread(() -> {
for (int i = 1; i<= 10; i++) {
try {
ticket.two();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"B").start();
new Thread(() -> {for (
int i = 1; i<= 10; i++) {
try {
ticket.thre();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"C").start();
}
}
class ticket{
private int num = 1;//设置初始值为1
Lock lock = new ReentrantLock();//使用lock锁来控制
Condition v = lock.newCondition();//由于需要不断切换线程,所以需要使用lock锁里面的Condition定向唤醒
Condition v1 = lock.newCondition();
Condition v2 = lock.newCondition();
public void one () throws InterruptedException {
lock.lock();
try {
while (num != 1) {
v.await();
}
//如果为1会走下面的实现
System.out.println(Thread.currentThread().getName() + "线程调用,数量为" + num);
num = 2;
v1.signal();
} catch (Exception e) {
System.out.println(e);
} finally {
lock.unlock();
}
}
public void two () throws InterruptedException {
lock.lock();
try {
while (num != 2) {
v1.await();
}
System.out.println(Thread.currentThread().getName() + "线程调用,数量为" + num);
num = 3;
v2.signal()
} catch (Exception e) {
System.out.println(e);
} finally {
lock.unlock();
}
}
public void thre () throws InterruptedException {
lock.lock();
try {
while (num != 3) {
v2.await();
}
System.out.println(Thread.currentThread().getName() + "线程调用,数量为" + num);
num = 1;
v.signal();
} catch (Exception e) {
System.out.println(e);
} finally {
lock.unlock();
}
}
}