1、代码示例
public class TestSyncro2 {
public static void main(String[] args) {
final Customer customer = new Customer();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
customer.withdraw(15000);
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
customer.deposit(10000);
}
});
t1.start();
t2.start();
}
}
class Customer{
private int amount = 10000;
public synchronized void withdraw(int amount){
System.out.println("withdraw start....");
if(this.amount < amount){
System.out.println("less for withdraw, waiting for deposit...");
try {
this.wait(); // 释放对象锁,并进入等待状态,直到另一个线程notify
} catch(Exception ex){
}
}
this.amount -= amount;
System.out.println(Thread.currentThread().getName() + " print " + this.amount);
System.out.println("withdraw end....");
}
public synchronized void deposit(int amount){
System.out.println("deposit start....");
this.amount += amount;
System.out.println(Thread.currentThread().getName() + " print " + this.amount);
this.notify(); // 随机唤醒一个等待此对象锁的线程,但是由于当前线程还没有释放锁,被唤醒的线程还不能立即获得对象锁而执行
try {
Thread.sleep(2000); // 测试被唤醒线程不能立即获得对象锁
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("deposit end....");
}
}
2、执行结果
withdraw start....
less for withdraw, waiting for deposit...
deposit start....
Thread-1 print 20000
deposit end....
Thread-0 print 5000
withdraw end....
3、结论
(1)wait会释放对象锁,并进入等待状态,直到另一个线程notify
(2)notify一次只随机通知一个线程进行唤醒,在执行了notify方法之后,当前线程不会马上释放该对象锁,呈wait状态的线程也不能马上获得该对象锁,要等到执行notify方法的线程将程序执行完 ,也就是退出sychronized代码块后,当前线程才会释放锁,处于wait状态的线程才可以获取该对象锁