zoukankan      html  css  js  c++  java
  • 多线程基础(三)线程通信

    系列目录

    线程通信

    1.基于synchronized

    • void wait()
      在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。

    • void notify()
      唤醒(队头)在此对象监视器上等待的单个线程。

    • void notifyAll()
      唤醒在此对象监视器上等待的所有线程。

    标记位:
    如果已存在的属性无法满足需求,通常在锁对象中增加标记位属性,为了实现线程的控制。
    如果是两个线程:boolean。
    如果是多个线程:int 1,2,3。

    2.基于Lock

    若使用lock,则程序中没有隐式同步监视器,也就不能使用上面三个方法进行通信。需要从显式锁上得到控制器Condition,在利用condition的三个方法进行条件控制:(原理同上)

    • await()
    • signal()
    • signalAll()

    3.案例

    package myCorrespond;
    /**
     * Account1用于演示进程通信
     * 通过wait与Notify控制
     * wait:阻塞并放弃监视器
     *
     *Account2通过condition保证同步
     * 需要显式定义锁对象,从锁对象上获取同步条件
     * 注:
     * 1.因为显式定义锁,所以不能使用wait与notify
     * 2.需要显示关锁
     */
    
    import java.util.Objects;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    class Account1 {
        private String accountNo;
        private double balance;
        //标志账户中是否已有存款
        private boolean f=false;
    
        public Account1(String accountNo, double balance) {
            this.accountNo = accountNo;
            this.balance = balance;
        }
    
        public String getAccountNo() {
            return accountNo;
        }
    
        public void setAccountNo(String accountNo) {
            this.accountNo = accountNo;
        }
    
        public double getBalance() {
            return balance;
        }
        public synchronized void draw(double drawAmount)  {
            try{
                if(!f){//没有存款
                    wait();
                }
                else{
                    //取钱
                    System.out.println(Thread.currentThread().getName()+"取钱:"+drawAmount);
                    balance-=drawAmount;
                    System.out.println("余额:"+balance);
                    f=false;
                    notifyAll();
                }
            }catch (Exception ex){
                ex.printStackTrace();
            }
        }
        public synchronized void deposit(double depositAmount){
            try{
                if(f){
                    wait();
                }
                else {
                    System.out.println(Thread.currentThread().getName()+" 存款:"+depositAmount);
                    balance+=depositAmount;
                    System.out.println("余额:"+balance);
                    f=true;
                    notifyAll();
                }
            }catch (Exception ex){
                ex.printStackTrace();
            }
        }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Account1 account = (Account1) o;
            return Objects.equals(accountNo, account.accountNo);
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(accountNo);
        }
    }
    
    class Account2{
        //显式定义锁对象
        private final Lock lock=new ReentrantLock();
        //从锁对象上拿到控制条件
        private final Condition condition=lock.newCondition();
        private String accountNo;
        private double balance;
        //标志账户中是否已有存款
        private boolean f=false;
        public Account2(String accountNo, double balance) {
            this.accountNo = accountNo;
            this.balance = balance;
        }
    
        public String getAccountNo() {
            return accountNo;
        }
    
        public void setAccountNo(String accountNo) {
            this.accountNo = accountNo;
        }
    
        public double getBalance() {
            return balance;
        }
        public void draw(double drawAmount)  {
            //加锁
            lock.lock();
            try{
                if(!f){//m欸有存款
                    condition.await();
                }
                else{
                    //取钱
                    System.out.println(Thread.currentThread().getName()+"取钱:"+drawAmount);
                    balance-=drawAmount;
                    System.out.println("余额:"+balance);
                    f=false;
                    condition.signalAll();
                }
            }catch (Exception ex){
                ex.printStackTrace();
            }finally{
                lock.unlock();
            }
        }
        public void deposit(double depositAmount){
            lock.lock();
            try{
                if(f){
                    condition.await();
                }
                else {
                    System.out.println(Thread.currentThread().getName()+" 存款:"+depositAmount);
                    balance+=depositAmount;
                    System.out.println("余额:"+balance);
                    f=true;
                    condition.signalAll();
                }
            }catch (Exception ex){
                ex.printStackTrace();
            }finally{
                lock.unlock();
            }
        }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }
            Account2 account = (Account2) o;
            return Objects.equals(accountNo, account.accountNo);
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(accountNo);
        }
    
    }
    
    
    class DrawThread extends Thread {
        private Account2 account;
        private double drawAmount;
    
        public DrawThread(String name,Account2 account,double drawAmount){
            super(name);
            this.account=account;
            this.drawAmount=drawAmount;
        }
    
        @Override
        public void run(){
            for(int i=0;i<100;i++){
                account.draw(drawAmount);
            }
        }
    }
    
    class depositThread extends Thread{
        private Account2 account;
        private double depositAmount;
    
        public depositThread(String name,Account2 account,double depositAmount){
            super(name);
            this.account=account;
            this.depositAmount=depositAmount;
        }
    
        @Override
        public void run(){
            for(int i=0;i<100;i++){
                account.deposit(depositAmount );
            }
        }
    }
    public class AccountMode{
        public static void main(String[] args) {
            Account2 account = new Account2("myaccount", 0);
            new DrawThread("取钱者",account,800).start();
            new depositThread("存钱者甲",account,800).start();
            new depositThread("存钱者已",account,800).start();
            new depositThread("存钱者丙",account,800).start();
        }
    
    }
  • 相关阅读:
    HDU2303(数论)大整数求余+素数筛选
    2015 多校联赛 ——HDU5360(贪心+优先队列)
    2015 多校联赛 ——HDU5363(快速幂)
    2015 多校联赛 ——HDU5353(构造)
    2015 多校联赛 ——HDU5348(搜索)
    2015 多校联赛 ——HDU5350(huffman)
    hibernate投影查询
    Hibernate中Criteria的完整用法
    mysql 常用查询语句记录
    ssh整合步骤整理
  • 原文地址:https://www.cnblogs.com/juzhuxiaozhu/p/12762551.html
Copyright © 2011-2022 走看看