JAVA多线程-线程间通信(2)

    技术2022-07-10  135

    除了jdk的锁synchronized的线程间可以通信,那我们之前讲的通过java的lock锁的线程之间可以互相通信吗?又是通过什么方式来通信的呢?lock当中又和wait和notify/notifyAll类锁的通信方式那就是awaitsignal/ signalAll,而且他们的用法也相似,我们看下代码:账户类:

    package com.ck.thread; import java.math.BigDecimal; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class Account {     private volatile BigDecimal balnace = new BigDecimal("0");     private Lock lock = new ReentrantLock();     private Condition condition = lock.newCondition();     //充值     public void cz() {         lock.lock();         try {             for(int i = 0; i<10; i++) {                 balnace = balnace.add(new BigDecimal("10"));                 if(balnace.compareTo(new BigDecimal("50")) == 0) {                    condition.signal();                    System.out.println("已经发出通知");                 }                 System.out.println("充值中.........");             }         }finally {             lock.unlock();         }     }     //消费     public void xf() throws InterruptedException {         lock.lock();         try {             if(balnace.compareTo(new BigDecimal("50")) < 0) {                 System.out.println("等待充值");                 condition.await();                 System.out.println("余额已经充足,开始消费");             }         }finally {             lock.unlock();         }     }             public BigDecimal getBalnace() {         return balnace;     }     public void setBalnace(BigDecimal balnace) {         this.balnace = balnace;     } }

    充值线程:

    package com.ck.thread; public class CzThread extends Thread{     private Account account;     public CzThread(Account account) {         this.account = account;     }         @Override     public void run() {         account.cz();     }     public Account getAccount() {         return account;     }     public void setAccount(Account account) {         this.account = account;     } }

    消费线程:

    package com.ck.thread; public class XfThread extends Thread{     private Account account;     public XfThread(Account account) {         super();         this.account = account;     }     @Override     public void run() {         try {             account.xf();         } catch (InterruptedException e) {             e.printStackTrace();         }     }     public Account getAccount() {         return account;     }     public void setAccount(Account account) {         this.account = account;     } }

     

    主线程:

    package com.ck.thread; public class MainThread {     public static void main(String[] args) throws InterruptedException {         Account account = new Account();         XfThread xf = new XfThread(account);         xf.setName("xf");         CzThread cz = new CzThread(account);         cz.setName("cz");                 xf.start();         cz.start();     } }

    运行结果:

    等待充值 充值中......... 充值中......... 充值中......... 充值中......... 已经发出通知 充值中......... 充值中......... 充值中......... 充值中......... 充值中......... 充值中......... 余额已经充足,开始消费

     

    然后我们把signal换成signalAll:

    package com.ck.thread; import java.math.BigDecimal; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class Account {     private volatile BigDecimal balnace = new BigDecimal("0");     private Lock lock = new ReentrantLock();     private Condition condition = lock.newCondition();     //充值     public void cz() {         lock.lock();         try {             for(int i = 0; i<10; i++) {                 balnace = balnace.add(new BigDecimal("10"));                 if(balnace.compareTo(new BigDecimal("50")) == 0) {                    condition.signalAll();                    System.out.println("已经发出通知");                 }                 System.out.println("充值中.........");             }         }finally {             lock.unlock();         }     }     //消费     public void xf() throws InterruptedException {         lock.lock();         try {             if(balnace.compareTo(new BigDecimal("50")) < 0) {                 System.out.println("等待充值");                 condition.await();                 System.out.println("余额已经充足,开始消费");             }         }finally {             lock.unlock();         }     }             public BigDecimal getBalnace() {         return balnace;     }     public void setBalnace(BigDecimal balnace) {         this.balnace = balnace;     } }

    运行结果:

    等待充值 充值中......... 充值中......... 充值中......... 充值中......... 已经发出通知 充值中......... 充值中......... 充值中......... 充值中......... 充值中......... 充值中......... 余额已经充足,开始消费

    await和signal/signalAll关于锁的释放已经通知方式与之前的wait与notify/notifyAll都是一样的,虽然原理方面不一样,具体的原理我们会在以后讲。

    Processed: 0.022, SQL: 12