今天在做多线程练习的时候,参考资料给的是使用extends继承Thread类的方式创建的子类对象,天然带有start()方法
题目如下:
/**
* 生产者-消费者问题
* 生产者最多生产20个产品,生产完就得等待
* 交由服务员来调度生产者和消费者
* 消费者没有能消费产品的时候,等待
**/
但是我本人是使用的implments runnable接口的方式来创建子类的多线程的。这一试不要紧,试完了发现BBQ了,在实际场景中,由于生产者和消费者虽然都实现了runnable接口,但是我在调用过程中,由于是implments runnable接口的方式,所以按照道理应该是要以Thread(runnable)的方式创建线程,然后借用Thread类本身来实现start()方法,但是我又创建对生产者和消费者对象,这也就导致了我new出来的生产者和消费者,没有使用Thread类创建,也没办法使用start()方法。
解决方法:
在一开始的过程中,我是这样设想的:
先看看thread类的start()方法怎么写的,我copy一份过来
于是我就去点进Thread类中查看start方法,后来发现里面很多变量是在之前就定义好的,我copy过来并不适用。
那么我就要开动我的小脑袋瓜了
既然我生产者和消费者实现了runnable接口,那我干脆在创建的生产者和消费者的基础上,再用Thread接口来实现好了
即:
Waiter w = new Waiter();
Producer p =new Producer(w);
Consumer c1 = new Consumer(w);
Consumer c2 = new Consumer(w);
Thread t1 = new Thread(p);
Thread t2 = new Thread(c1);
Thread t3 = new Thread(c2);
多出一步来,豁然开朗,最后也是成功实现了题目要求
下面是完整代码:
import static java.lang.Thread.sleep;
/**
* 生产者-消费者问题
* 生产者最多生产20个产品,生产完就得等待
* 消费者没有能消费产品的时候,等待
* @author Dionysus_xu
* @create 2022-03-01-17:30
*/
public class PoC_Problem {
public static void main(String[] args) {
Waiter w = new Waiter();
Producer p =new Producer(w);
Consumer c1 = new Consumer(w);
Consumer c2 = new Consumer(w);
Thread t1 = new Thread(p);
Thread t2 = new Thread(c1);
Thread t3 = new Thread(c2);
t1.setName("生产者1");
t2.setName("消费者1");
t3.setName("消费者2");
t1.start();
t2.start();
t3.start();
}
}
class Waiter{
private int Produce = 0;
public synchronized void createProduce(){
if(Produce < 20){
Produce++;
System.out.println(Thread.currentThread().getName()+":生产了第" + Produce + "件产品");
notifyAll();
}else {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void consumeProduce() {
if(Produce > 0){
System.out.println(Thread.currentThread().getName()+":消费了第" + Produce + "件产品");
Produce--;
notifyAll();
}else {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Producer implements Runnable{
private Waiter waiter = null;
public Producer(Waiter waiter){
this.waiter = waiter;
}
@Override
public void run() {
while (true){
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
waiter.createProduce();
}
}
}
class Consumer implements Runnable{
private Waiter waiter = null;
public Consumer(Waiter waiter){
this.waiter = waiter;
}
@Override
public void run() {
while (true){
try {
sleep(240);
} catch (InterruptedException e) {
e.printStackTrace();
}
waiter.consumeProduce();
}
}
}