• java1


    0x00 什么是Conditional Variable

    通常,线程进入临界区,却发现在某一条件满足后它才能执行

    要使用一个条件对象管理那些已经获得了锁但是却不能做有用工作的进程

    也就是说,如果条件不满足,则等待。当条件满足时,等待该条件的线程将被唤醒

    举个简单的例子,handle_file线程要处理文件,download_file线程要下载文件

    但是要先下载后才能打开,所以,handle_file即使获得了锁,也要等待download_file把文件下载完

    这时候就需要条件变量

    0x01 取款和存款问题

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
     
    /**
    * Java线程:条件变量
    *
    * @author leizhimin 2009-11-5 10:57:29
    */
    public class Test {
    public static void main(String[] args) {
    //创建并发访问的账户
    MyCount myCount = new MyCount("95599200901215522", 10000);
    //创建一个线程池
    ExecutorService pool = Executors.newFixedThreadPool(2);
    Thread t1 = new SaveThread("张三", myCount, 2000);
    Thread t2 = new SaveThread("李四", myCount, 3600);
    Thread t3 = new DrawThread("王五", myCount, 2700);
    Thread t4 = new SaveThread("老张", myCount, 600);
    Thread t5 = new DrawThread("老牛", myCount, 1300);
    Thread t6 = new DrawThread("胖子", myCount, 800);
    //执行各个线程
    pool.execute(t1);
    pool.execute(t2);
    pool.execute(t3);
    pool.execute(t4);
    pool.execute(t5);
    pool.execute(t6);
    //关闭线程池
    pool.shutdown();
    }
    }
     
    /**
    * 存款线程类
    */
    class SaveThread extends Thread {
    private String name; //操作人
    private MyCount myCount; //账户
    private int x; //存款金额
     
    SaveThread(String name, MyCount myCount, int x) {
    this.name = name;
    this.myCount = myCount;
    this.x = x;
    }
     
    public void run() {
    myCount.saving(x, name);
    }
    }
     
    /**
    * 取款线程类
    */
    class DrawThread extends Thread {
    private String name; //操作人
    private MyCount myCount; //账户
    private int x; //存款金额
     
    DrawThread(String name, MyCount myCount, int x) {
    this.name = name;
    this.myCount = myCount;
    this.x = x;
    }
     
    public void run() {
    myCount.drawing(x, name);
    }
    }
     
     
    /**
    * 普通银行账户,不可透支
    */
    class MyCount {
    private String oid; //账号
    private int cash; //账户余额
    private Lock lock = new ReentrantLock(); //账户锁
    private Condition _save = lock.newCondition(); //存款条件
    private Condition _draw = lock.newCondition(); //取款条件
     
    MyCount(String oid, int cash) {
    this.oid = oid;
    this.cash = cash;
    }
     
    /**
    * 存款
    *
    * @param x 操作金额
    * @param name 操作人
    */
    public void saving(int x, String name) {
    lock.lock(); //获取锁
    if (x > 0) {
    cash += x; //存款
    System.out.println(name + "存款" + x + ",当前余额为" + cash);
    }
    _draw.signalAll(); //唤醒所有等待线程。
    lock.unlock(); //释放锁
    }
     
    /**
    * 取款
    *
    * @param x 操作金额
    * @param name 操作人
    */
    public void drawing(int x, String name) {
    lock.lock(); //获取锁
    try {
    if (cash - x < 0) {
    _draw.await(); //阻塞取款操作
    } else {
    cash -= x; //取款
    System.out.println(name + "取款" + x + ",当前余额为" + cash);
    }
    _save.signalAll(); //唤醒所有存款操作
    } catch (InterruptedException e) {
    e.printStackTrace();
    } finally {
    lock.unlock(); //释放锁
    }
    }
    }

    MyCount里面有取款和存款的方法,设置多个线程分别执行这两个方法

    当一个取款线程获取了锁,但是发现钱不够了,然后就会进入等待队列,等待存款的进程将其唤醒

  • 相关阅读:
    轻松自动化---selenium-webdriver(python) (八)
    轻松自动化---selenium-webdriver(python) (七)
    轻松自动化---selenium-webdriver(python) (六)
    轻松自动化---selenium-webdriver(python) (五)
    轻松自动化---selenium-webdriver(python) (四)
    轻松自动化---selenium-webdriver(python) (三)
    轻松自动化---selenium-webdriver(python) (二)
    轻松自动化---selenium-webdriver(python) (一)
    容器在 Weave 中如何通信和隔离?- 每天5分钟玩转 Docker 容器技术(65)
    Weave 网络结构分析
  • 原文地址:https://www.cnblogs.com/gride-glory/p/7603719.html
Copyright © 2020-2023  润新知