除了jdk的锁synchronized的线程间可以通信,那我们之前讲的通过java的lock锁的线程之间可以互相通信吗?又是通过什么方式来通信的呢?lock当中又和wait和notify/notifyAll类锁的通信方式那就是await和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.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都是一样的,虽然原理方面不一样,具体的原理我们会在以后讲。