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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 22 - 16 多线程之生产者和消费者的问题相关的知识,希望对你有一定的参考价值。

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

技术分享

 

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

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

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

 

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

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

 

* 资源类:Student

1 public class Student {
2     
3         String name;
4         int age;
5 }

 

* 设置学生数据: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(消费者)

 1 public class GetThread implements Runnable {
 2 
 3     private Student s;
 4     public GetThread(Student s){
 5         this.s = s;
 6     }
 7     public void run() {
 8             //获取信息  消费者
 9             //锁的对象,同SetThread
10         while(true){
11             synchronized (s){
12                 System.out.println(s.name +"--" + s.age);
13             }
14         }
15 
16     }
17 
18 }    

 

* 测试类:StudentDemo

 1 public class StudentDemo {
 2 
 3 
 4     public static void main(String[] args) {
 5         
 6         //创建资源对象
 7         Student s = new Student();
 8         
 9         //创建录入和获取类的对象
10         SetThread st = new SetThread(s);
11         GetThread gt = new GetThread(s);
12         
13         //创建线程对象
14         Thread t1 = new Thread(st);
15         Thread t2 = new Thread(gt);
16         
17         //启动线程
18         t1.start();
19         t2.start();
20 
21     }
22 
23 }

 

结果:

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

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

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

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

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

 

以上是关于java 22 - 16 多线程之生产者和消费者的问题的主要内容,如果未能解决你的问题,请参考以下文章

java 多线程 22 :生产者/消费者模式 进阶 利用await()/signal()实现

java 多线程并发系列之 生产者消费者模式的两种实现

Java多线程系列-之生产消费者问题

java 多线程系列基础篇之生产消费者问题

JUC - 多线程之Synchronized和Lock锁;生产者消费者模式

Java多线程系列--“基础篇”11之 生产消费者问题