zoukankan      html  css  js  c++  java
  • java线程之线程通信控制

    在上篇我们看到,A线程往公共资源库(对象)提供了一条数据,然后B线程从库中提取了数据并打印出来。

    实际项目中,我们不可能只往库中提供一条数据,而且库的大小也不会是无穷大的,那么我们就会有这样一

    个需求:A线程提供了一定的数据量后就暂停,等待B线程全部取走之后(因为B再不来取的话,库就装不下

    了),A线程再往其中添加数据,如此往复。这里存在两种方法;

    1.资源库对象的wait()方法和notify()方法/notifyAll()方法

     1 public class Share {
     2     String name;
     3     String sex;
     4     //用empty来表示库中是否有数据
     5     boolean empty = true;
     6 
     7     // 线程A的任务,提供数据
     8     synchronized public void product(String name, String sex) {
     9         try {
    10             while(!empty) {
    11                 //当库中数据不为空时,A线程不能向其添加数据,小憩一会儿
    12                 this.wait();
    13             }
    14             //当库中数据为空时,A线程向其添加数据
    15             this.name = name;
    16             this.sex = sex;
    17             //添加完成之后,更改库中数据状态为不空,并唤醒其他线程来拿数据
    18             empty=false;
    19             this.notifyAll();
    20         } catch (InterruptedException e) {
    21             e.printStackTrace();
    22         }
    23 
    24     }
    25 
    26     // 线程B的任务,提取(显示)数据
    27     synchronized public void show() {
    28         try {
    29             while(empty) {
    30                 //当库中数据为空时,B线程不能获取数据,小憩一会儿
    31                 this.wait();
    32             }
    33             //当库中数据不为空时,B线程获取数据并打印
    34             System.out.println("姓名:" + this.name + "性别:" + this.sex);
    35             //拿完数据之后,更改库中数据状态为空,并唤醒其他线程继续写数据
    36             empty=true;
    37             this.notifyAll();
    38         } catch (InterruptedException e) {
    39             e.printStackTrace();
    40         }
    41     }
    42 }

    wait()方法和notifyAll()方法只能由同步监听器对象来调用,就是这里说的资源库对象。

    2.同步锁(Lock)和Condition接口

    之前讲线程同步时有说到同步锁的方法,这种方法是没有同步监听器对象的,那么上面的wait()等方法就不能用了,

    但是不用担心,java5在推出同步锁的时候也为其通信控制提供了一个方法获得Condition对象,来实现通信控制

     1 public class Share {
     2     String name;
     3     String sex;
     4     //创建锁
     5     final Lock lock = new ReentrantLock();
     6     //创建Condition对象
     7     Condition condition = lock.newCondition();
     8     // 用empty来表示库中是否有数据
     9     boolean empty = true;
    10 
    11     // 线程A的任务,提供数据
    12     public void product(String name, String sex) {
    13         lock.lock();//上锁
    14         try {
    15             while (!empty) {
    16                 // 当库中数据不为空时,A线程不能向其添加数据,小憩一会儿
    17                 condition.await();
    18             }
    19             // 当库中数据为空时,A线程向其添加数据
    20             this.name = name;
    21             this.sex = sex;
    22             // 添加完成之后,更改库中数据状态为不空,并唤醒其他线程来拿数据
    23             empty = false;
    24             condition.signalAll();
    25         } catch (InterruptedException e) {
    26             e.printStackTrace();
    27         }
    28         lock.unlock();//解锁
    29     }
    30 
    31     // 线程B的任务,提取(显示)数据
    32      public void show() {
    33          lock.lock();//上锁
    34         try {
    35             while (empty) {
    36                 // 当库中数据为空时,B线程不能获取数据,小憩一会儿
    37                 condition.await();
    38             }
    39             // 当库中数据不为空时,B线程获取数据并打印
    40             System.out.println("姓名:" + this.name + "性别:" + this.sex);
    41             // 拿完数据之后,更改库中数据状态为空,并唤醒其他线程继续写数据
    42             empty = true;
    43             condition.signalAll();
    44         } catch (InterruptedException e) {
    45             e.printStackTrace();
    46         }
    47         condition.signalAll();//解锁
    48     }
    49 }
  • 相关阅读:
    GCD与LCM
    命名空间的使用
    [模板][持续更新]欧拉回路与欧拉路径浅析
    二进制GCD算法解析
    [模板]LCA的倍增求法解析
    [模板]字符串哈希的简易做法
    11、Android--屏幕适配
    10、Android--Shape
    09、Android--Fragment
    08、Android--BroadcastReceiver
  • 原文地址:https://www.cnblogs.com/eco-just/p/7772348.html
Copyright © 2011-2022 走看看