java 22 - 16 多线程之生产者和消费者的问题

时间:2023-04-11 09:38:26

生产者和消费者问题的描述图

java 22 - 16   多线程之生产者和消费者的问题

通过上图,我们可以发现:

生产者和消费者使用的都是同一个资源(肉包子)

所以,当使用线程的时候,这两类的锁也是同一把锁(为了避免出现线程安全问题)

例子:学生信息的录入和获取

  * 资源类:Student
  * 设置学生数据:SetThread(生产者)
  * 获取学生数据:GetThread(消费者)
  * 测试类:StudentDemo

* 资源类:Student

 public class Student {

         String name;
int age;
}

* 设置学生数据:SetThread(生产者)

public class SetThread implements Runnable {
private int x = 0; // 因为SetThread和Getthread两个类使用的都是同一个资源
// 所以,在创建一个资源对象,再通过构造方法传递给其它的类
private Student s; public SetThread(Student s) {
this.s = s;
} public void run() {
// 录入信息(生产者) while (true) { // 加锁,且SetThread和Getthread两个类使用的是同一把锁,所以锁的对象是资源对象s
synchronized (s) {
if (x % 2 == 0) {
s.name = "张三";
s.age = 23;
} else {
s.name = "李四";
s.age = 24;
}
x++;
}
}
} }

* 获取学生数据:GetThread(消费者)

 public class GetThread implements Runnable {

     private Student s;
public GetThread(Student s){
this.s = s;
}
public void run() {
//获取信息 消费者
//锁的对象,同SetThread
while(true){
synchronized (s){
System.out.println(s.name +"--" + s.age);
}
} } }

* 测试类:StudentDemo

 public class StudentDemo {

     public static void main(String[] args) {

         //创建资源对象
Student s = new Student(); //创建录入和获取类的对象
SetThread st = new SetThread(s);
GetThread gt = new GetThread(s); //创建线程对象
Thread t1 = new Thread(st);
Thread t2 = new Thread(gt); //启动线程
t1.start();
t2.start(); } }

结果:

  生产者SetThread类不断地录入学生信息(可以看成不断生产包子?)

而消费者GetThread类则不断地获取所录入的信息(买包子?)

当然,最理想的状态是生产者生产1个,消费者就立马消费1个....

但,这里还不是这种理想状态,两者还是得抢占CPU的资源,若是生产的多,则就堆积着等消费者。

  若是消费者抢占的资源多,则一直消费的都是同一个包子?。。