Java线程间通信问题分析(生产者消费者模型)

线程间通信问题:
不同线程间针对 同一资源进行操作的问题

生产者消费者模型:
生产者(设置线程)和消费者(获取线程)对同一资源对象进行操作

实现:
一、学生类
Student.java
1
public class Student{
2
  
3
  private String name;
4
  private int age;
5
  public Student(){
6
      this.name = name;
7
      this.age = age;
8
  }
9
10
  
11
}

二、生产者类
SetThread.java
1
public class SetThread implements Runnable{
2
3
    private Student s;
4
    private count = 0;
5
    public SetThread(Student s){
6
        this.s = s;
7
    }
8
    @Override
9
    public void run(){
10
        while(true){
11
            if(count%2==0){
12
                s.name = "Mike";//设置资源属性
13
                s.age = 20;
14
            }else{
15
                s.name = "Lily";//设置资源属性
16
                s.age = 19;
17
            }
18
            
19
        }
20
        
21
    }
22
23
}

三、消费者类
GetThread.java
1
public class GetThread implements Runnable{
2
3
    private Student s;
4
5
6
    public GetThread(Student s){
7
        this.s = s;
8
    }
9
    @Override
10
    public void run(){
11
        
12
        System.out.println(s.name + "----" + s.age);
13
    }
14
15
16
}

四、测试类
StudentTest.java
1
public void StudentTest{
2
3
    public static void main(String[] agrs){
4
    
5
        Student s = new Student("Mike",20);
6
7
        SetThread st = new SetThread(s);
8
        GetThread gt = new GetThread(s);
9
        //开启线程
10
        Thread t1 = new Thread(st);
11
        Thread t2 = new Thread(gt);
12
        t1.start();
13
        t2.start();
14
15
    }
16
17
}

产生问题:
1.只有t1线程先赋值,t2线程才能打印出值,否则t2打印出null
2.出现线程安全问题:1.共享资源 2.多线程 3.同时操作共享资源

解决问题:
1.对生产者(SetThread)、消费者(GetThread)都加锁---解决线程安全问题
2.加入等待唤醒机制------解决消费者线程比生产者线程先执行的问题(null的问题)
---------生产者:有产品(Student已赋值)则等待wait。没有产品(Student没有赋值)则生产赋值。
---------消费者: 有产品(Student已赋值)则消费。没有产品(Student没有赋值)则等待wait。
---------方法:wait()  和  notify()唤醒单个线程   notifyAll()唤醒所有线程

-------------------------------------------------------------------------------------------------------------
改进版 Student.java
1
public class Student{
2
  
3
  private String name;
4
  private int age;
5
  private boolean hasData= false;//默认没有数据
6
  public Student(){
7
      this.name = name;
8
      this.age = age;
9
  }
10
11
  
12
}
改进版 SetThread.java
1
public class SetThread implements Runnable{
2
    private Student s;
3
    private count = 0;
4
    public SetThread(Student s){
5
        this.s = s;
6
    }
7
    @Override
8
    public void run(){
9
        while(true){
10
        synchronized(s){//1.加锁解决线程安全问题
11
            if(s.hasData){//2.生产者判断是否有数据
12
                //已有数据,等待,并唤醒消费者消费
13
                s.wait();
14
            }
15
            //没有数据,则赋值
16
            s.hasData = true;
17
            if(count%2==0){
18
                s.name = "Mike";//设置资源属性
19
                s.age = 20;
20
            }else{
21
                s.name = "Lily";//设置资源属性
22
                s.age = 19;
23
            }
24
            s.notify();//唤醒消费者线程
25
        }
26
            
27
            
28
        }
29
        
30
    }
31
}
改进版Get Thread.java
1
public class GetThread implements Runnable{
2
    private Student s;
3
4
    public GetThread(Student s){
5
        this.s = s;
6
    }
7
    @Override
8
    public void run(){
9
        synchronized(s){//1.加锁解决线程安全问题
10
            if(s.hasData){//2.消费者判断是否有数据
11
                //已有数据,消费
12
                System.out.println(s.name + "----" + s.age);
13
                s.notify();//唤醒消费者线程
14
            }
15
            //没有数据,则等待,并唤醒生产者生产数据
16
            s.wait();
17
        }
18
        
19
    }
20
}

生产者消费者模型总结:
1.产生条件:生产者(线程1),消费者(线程2)对同一变量(产品)进行读写。

2.产生问题:
-------------生产者和消费者存在线程安全问题(生产者生产一半,CPU就让消费者消费)
-------------消费者要在生产者生产完后才能消费(出现消费者消费空产品的情况)

3.解决方法:
--------------生成者和消费者同时加锁(synchronized关键字对产品对象(student)加锁)
--------------等待唤醒机制



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值