这次还理解不了多线程的生产者和消费者问题,觉得我凉凉了。

首先贴一段代码
消费者

import java.util.List;
public class Consume implements Runnable {
 private List container = null;
 private int count;
 public Consume(List lst) {
  this.container = lst;
 }
 public void run() {
  while (true) {
   synchronized (container) {
    if (container.size() == 0) {
     try {
      container.wait();// 容器为空,放弃锁,等待生产
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
    }
    try {
     Thread.sleep(1000);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    container.remove(0);
    container.notify();
    System.out.println("我吃了" + (++count) + "个");
   }
  }
 }
}

生产者
import java.util.List;
public class Product implements Runnable {
private List container = null;
private int count;
public Product(List lst) {
this.container = lst;
}
public void run() {
while (true) {
synchronized (container) {
if (container.size() > MultiThread.MAX) {
// 如果容器超过了最大值,就不要在生产了,等待消费
try {
container.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
container.add(new Object());
container.notify();
System.out.println(“我生产了” + (++count) + “个”);

}
}
}
}
测试方法

public class MultiThread {
 private List container = new ArrayList();
 public final static int MAX = 5;
 public static void main(String args[]) {
  MultiThread m = new MultiThread();
  new Thread(new Consume(m.getContainer())).start();
  new Thread(new Product(m.getContainer())).start();
 }
 public List getContainer() {
  return container;
 }
 public void setContainer(List container) {
  this.container = container;
 }
}

做java 也有一段时间了,但是因为平时遇到的多线程问题也不多,所以对多线程通讯之类的问题还是有一些不太了解。拿个最经典的生产者和消费者的例子自己研究一下。

上面这个案例中我们可以看到3个内容
wait:指当前线程直接放弃锁,将锁归还,需要本锁的线程回到起跑线,同时去争夺
sleep:故名思意,就是让线程睡,让这个线程等待一段时间,不会放弃锁,等待时间过后会继续执行当前线程
notify:随机唤醒一个被wait的线程,注意,执行了

注意:以上3个方法只有在synchronized的代码块中可以使用,因为只有持有锁,才能放弃锁,或者唤醒锁。

问题:我最奇怪的是理解不了这部分当生产者生成了东西之后执行了container.notify();那么消费者应该被唤醒了啊,为什么它不立即消费呢,而生产者还是在一直生产。

答案:其实是这样的,当锁执行了notify()只会将抛弃锁的对象重新进入就绪状态,随时能够获得锁,进而去执行,理解这里处于就绪状态,而不是运行状态,但是当生产者生产到最大值以后就不一样了,锁直接被放弃了,因为只启用了2个线程,那么下一次一定是消费者拿到锁,只有消费值执行了notify才会让生产者的线程处于就绪状态准备拿到执行机会进行生产。

如果解决了你的问题,点个赞吧

猜你喜欢

转载自blog.csdn.net/qq_42584411/article/details/105026582