四 java------线程---线程通信

本文深入探讨线程同步和通信技巧,通过生产者和消费者问题的实例,讲解如何使用同步代码块、实现Runnable接口及wait、notify方法,确保线程间的正确交互。

线程一些小知识的整理。

需求: 使用线程同步和通信,解决生产者和消费者的问题!

技能:
  1.线程同步---推荐使用同步代码块(同步锁---建议使用共享资源)
  2.实现多线程----推荐使用实现Runnable接口
  3.通信的方法---三个方法
      说明: 他们都存在Object类当中,因为Object类是任何的类的父类,子类都可以通过继承关系,继承三个通信的方法!
           根据三个方法的定义,他们都使用了final修饰,也就是说,子类只能继承不能重写!
      线程等待---wait()方法
        特点:1.在线程等待的同时,释放同步锁!
            2.只能等待另外一个线程的通知/唤醒,此线程才能继续运行!
        笔试题: wait()方法和sleep()方法的异同! --- 作业题。
      线程的唤醒----notify()方法
         特点: 只能唤醒等待的线程,不能唤醒休眠的线程!
      唤醒所有的线程---notifyAll()方法
         特点: 唤醒所有正在等待的线程
              对于正在等待的线程,那个线程优先级别高,就先唤醒谁!(谨记: 即使全部唤醒,同时线程的优先级高的线程,也不一定先执行!)
代码区:(重中之重)
public class Consumer implements Runnable {
 //属性---成员变量
 private Product pro;
 //get set方法
 public Product getPro() {
  return pro;
 }

 public void setPro(Product pro){
  this.pro = pro;
 }
 //构造方法
 public Consumer() {
  super();
 }
 public Consumer(Product pro) {
  super();
  this.pro = pro;
 }

 //重写run()方法
 public void run() {
  //消费产品
  while(true){
   //通过产品类对象,调用消费方法
   pro.get();
  }
 }
}
public class Producer implements Runnable{
 
 //定义属性---成员变量
 private Product pro = null;
 //get set方法
    public Product getPro() {
  return pro;
 }
 public void setPro(Product pro) {
  this.pro = pro;
 }
 //构造方法
 public Producer() {
  super();
  // TODO Auto-generated constructor stub
 }
 //目的: 为了防止出现空指针异常
 public Producer(Product pro) {
  super();
  this.pro = pro;
 }
 //重写run方法
 public void run() {
  //定义一个变量 i 初始化值为0  目的: 为了区分生产馒头还是玉米饼  如果i%2==0 生产馒头,反之,生产玉米饼
  int i =0;
  //循环的进行生产,以便能生产馒头和玉米饼,如果不使用循环语句,则只会生产一次,而且只是馒头
  while(true){
   if(i%2==0){
    pro.put("馒头", "白色");
   }else{
    pro.put("玉米饼", "黄色");
   }
   //改变if语句当中的布尔值,如果为true,则生产馒头,反之,生产玉米饼
   i++;
  }
 }
}
/**
 * Product类: 产品类
 *    目的:1.使用此类对象,充当同步锁(同步监视器)
 *         2.把产品的属性以及get set方法和构造方法,写入到此类,供以后使用
 *           同时,把生产的方法和消费的方法,也写入到此类中!
 *           原因: 在使用同步的时候,会调用这个两个方法!
 *
 *    生产馒头和玉米饼
 *       馒头---白色
 *       玉米饼---黄色
 */
public class Product {
     //属性
  private String name;
  private String color;
  //定义一个boolean类型的变量,目的: 为了在生产以及消费当中,进行判断而用
  private boolean isProduct = false;
  //get set方法
  public String getName() {
   return name;
  }
  public void setName(String name) {
   this.name = name;
  }
  public String getColor() {
   return color;
  }
  public void setColor(String color) {
   this.color = color;
  }
  //构造方法
  public Product() {
   super();
  }
  public Product(String name, String color) {
   super();
   this.name = name;
   this.color = color;
  }
  //toString()方法
  @Override
  public String toString() {
   return "Product [name=" + name + ", color=" + color + "]";
  }
  //生产和消费的方法---要求这两个方法使用同步方法!
  // 生产的方法,此方法的形参: 产品的名称和产品的颜色
  public  synchronized  void  put(String name,String color){
   //1.1 先进性判断,消费者判断仓库当中是否有产品
   if(isProduct){
    try {
     wait();
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
   //1.2 生产产品
   this.name=name;
   try {
    Thread.sleep(100);
   } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   this.color=color;
   System.out.println(Thread.currentThread().getName()+"生产:"+name+"     "+color);
   //1.3 修改boolean类型的变量,目的: 说明仓库已经有产品了,不用再生产了
   isProduct = true;
   //1.4 唤醒消费者线程
   notify();
   
  }
  //消费的方法
  public synchronized void get(){
   //1.1 判断
   if(!isProduct){
    try {
     wait();
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   }
   //1.2 消费产品
   System.out.println(Thread.currentThread().getName()+"消费产品:"+this.getName()+"---"+this.getColor());
   //1.3 修改boolean变量的值
   isProduct = false;
   //1.4 唤醒生产者线程,进行生产
   notify();
  }
}
public class Test {
 public static void main(String[] args) {
  //1.创建产品类对象,目的: 为生产者线程和消费线程的构造方法做准备
      Product pro = new Product();
  //2.创建Runnalbe接口对象
      Runnable r1 = new Producer(pro);
      Runnable r2 = new Consumer(pro);
     //3.借助Thread类,创建线程,并启动线程
      Thread t1  = new Thread(r1,"生产者------");
      Thread t2  = new Thread(r2,"消费者---");
      t1.start();
      t2.start();    
 }
}

原博地址(也是我,O(∩_∩)O哈哈~):http://m15231417197.lofter.com/

练习代码地址(嘿嘿嘿):https://download.youkuaiyun.com/download/m15231417197/10716486

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值