Java多线程通信实现方式详解

这篇文章主要介绍了Java多线程通信实现方式详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

线程通信的方式:

1、共享变量

线程间通信可以通过发送信号,发送信号的一个简单方式是在共享对象的变量里设置信号值。线程A在一个同步块里设置boolean型成员变量hasDataToProcess为true,线程B也在同步代码块里读取hasDataToProcess这个成员变量。这个简单的例子使用了一个持有信号的对象,并提供了set和get方法。

public class MySignal1 {
  //共享的变量
  private boolean hasDataToProcess = false;

  //取值
  public boolean getHasDataProcess() {
    return hasDataToProcess;
  }

  //存值
  public void setHasDataToProcess(boolean hasDataToProcess) {
    this.hasDataToProcess = hasDataToProcess;
  }

  public static void main(String[] args) {
    //同一个对象
    final MySignal1 my = new MySignal1();
    //线程1设置hasDataToProcess值为true
    final Thread t1 = new Thread(new Runnable() {
      @Override
      public void run() {
        my.setHasDataToProcess(true);
      }
    });
    t1.start();
    //线程2取这个值hasDataToProcess
    Thread t2 = new Thread(new Runnable() {
      @Override
      public void run() {
        try {
          //等待线程1完成后取值
          t1.join();
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        my.getHasDataProcess();
        System.out.println("t1改变以后的值:"+my.getHasDataProcess());
      }
    });
    t2.start();
  }
}

运行结果如下:

t1改变以后的值:true

2、等待/唤醒(wait/notify)机制

以资源为例,生产者生产一个资源,通知消费者就消费掉一个资源,生产者继续生产资源,消费者消费资源,以此循环,代码如下。

import sun.security.util.Password;

//资源类
class Resource {
  private String name;
  private int count = 1;
  private boolean flag = false;

  public synchronized void set(String name) {
    //生产资源
    while (flag) {
      try {
        //线程等待
        wait();
      } catch (InterruptedException e) {
      }
    }
    this.name = name + "----" + count + "+++++";
    System.out.println(Thread.currentThread().getName() + "..生产者..." + this.name);
    flag = true;
    //唤醒等待中的消费者
    this.notifyAll();
  }

  public synchronized void out() {
    //消费资源
    while (!flag) {
      try {
        //线程等待,生产者生产资源
        wait();
      } catch (InterruptedException e) {
      }
    }
    System.out.println(Thread.currentThread().getName() + "...消费者..." + this.name);
    flag = false;
    //唤醒消费者,生产资源
    this.notifyAll();
  }
}

//生产者
class Producer implements Runnable {
  private Resource rs;

  public Producer(Resource rs) {
    this.rs = rs;
  }

  //生产者生产资源
  @Override
  public void run() {
    while (true) {
      rs.set("商品");
    }
  }
}

//消费者消费资源
class Consumer implements Runnable {
  private Resource rs;

  public Consumer(Resource rs) {
    this.rs = rs;
  }

  //消费者消费资源
  @Override
  public void run() {
    while (true) {
      rs.out();
    }
  }
}

public class ProducerConsumerDemo {
  public static void main(String[] args) {
    Resource r = new Resource();
    Producer p = new Producer(r);
    Consumer c = new Consumer(r);
    Thread t1 = new Thread(p);
    Thread t2 = new Thread(c);
    t1.start();
    t2.start();
  }
}

运行结果如下:

Thread-0..生产者...商品----1+++++
Thread-1...消费者...商品----1+++++
Thread-0..生产者...商品----1+++++
Thread-1...消费者...商品----1+++++
Thread-0..生产者...商品----1+++++
Thread-1...消费者...商品----1+++++
Thread-0..生产者...商品----1+++++

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

相关文章

摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠...
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠...
今天犯了个错:“接口变动,伤筋动骨,除非你确定只有你一个...
Writer :BYSocket(泥沙砖瓦浆木匠)微 博:BYSocket豆 瓣:...
本文目录 线程与多线程 线程的运行与创建 线程的状态 1 线程...