问题见代码中:
Lock对象是不是可以复用?
1 public static class Account{ 2 private static Lock lock = new ReentrantLock(); 3 private static Condition newDeposit = lock.newCondition(); 4 private int balance = 0; 5 6 public int getBalance(){} 7 public void withdraw(int amount) 8 { 9 lock.lock();//Acquire the lock 10 try{ 11 while(balance < amount){ 12 System.out.println("\t\tWait for a deposit"); 13 newDeposit.await();//任务等待 14 } 15 balance -= amount; 16 System.out.println("\t\tWithdraw" + amount + "\t\t" + getBalance()); 17 } 18 catch(InterruptedException ex){ 19 ex.printStackTrace(); 20 } 21 finally{ 22 lock.unlock; 23 } 24 } 25 public void depoait(int amount) 26 { 27 lock.lock();//在withdraw 等待的时候,withdraw中的lock没有释放,此处为什么能获得lock? 28 try{ 29 balance += amount; 30 while(balance < amount){ 31 System.out.println("Deposit "+amount + "\t\t\t\t\t" + getBalance); 32 newDeposit.signalAll(); 33 } 34 35 } 36 finally{ 37 lock.unlock; 38 } 39 } 40 }
给你个例子和JDK API有关await方法的解释,希望你能看懂,多理解下API的解释和调试下代码就能看懂。
例子:
package overloadtest; 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; public class ThreadCooperation { private static Account account = new Account(); public static void main(String[] args) { ExecutorService executor = Executors.newFixedThreadPool(2); executor.execute(new DepositeTask()); executor.execute(new WithdrawTask()); executor.shutdown(); System.out.println("Thread 1\t\tThread2\t\tBalance"); } private static class DepositeTask implements Runnable { @Override public void run() { // TODO Auto-generated method stub try { while (true) { account.deposite((int) (Math.random() * 10) + 1); Thread.sleep(1000); } } catch (Exception ex) { ex.printStackTrace(); } } } private static class WithdrawTask implements Runnable { @Override public void run() { // TODO Auto-generated method stub while (true) { account.withdraw((int) (Math.random() * 10) + 1); } } } private static class Account { private static Lock lock = new ReentrantLock(); private static Condition newDeposite = lock.newCondition(); private int balance = 0; public int getBalance() { return this.balance; } public void withdraw(int amount) { lock.lock(); try { while (this.balance < amount) { newDeposite.await(); // super.wait(); } balance -= amount; System.out.println("\t\twithdraw " + amount + "\t\t" + getBalance()); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { lock.unlock(); } } public void deposite(int amount) { lock.lock(); try { balance += amount; System.out.println("deposite:" + amount + "\t\t\t\t" + getBalance()); newDeposite.signal(); // super.notifyAll(); } catch (Exception ex) { ex.printStackTrace(); } finally { lock.unlock(); } } } }
await
void await() throws InterruptedException
与此 Condition
相关的锁以原子方式释放,并且出于线程调度的目的,将禁用当前线程,且在发生以下四种情况之一 以前,当前线程将一直处于休眠状态:
Condition
的 signal()
方法,并且碰巧将当前线程选为被唤醒的线程;或者Condition
的 signalAll()
方法;或者在所有情况下,在此方法可以返回当前线程之前,都必须重新获取与此条件有关的锁。在线程返回时,可以保证 它保持此锁。
可以。 你这个例子呢。。 直接用AtomicInteger就可以搞定的。
生产者消费者模式,建议先用最原始的同步快、wait和notify实现,再用这些高层的封装实现