今天在做多线程练习的时候,参考资料给的是使用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(); } } }