小练习:创建两个账户,每个人存钱五十次,总共存钱100次,两个账户交替存钱。
利用实现接口的方式创建两个线程:
核心代码块:
@Override
public void run () {
while (number<100) {
synchronized (this){
notify();
System.out.println(Thread.currentThread().getName()+"存款余额为:" + balance);
number++;
balance++;
try {
Thread.sleep(1);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
try {
wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
运行结果:程序没有结束,只能手动结束。
分析原因:可能是因为用了wait()函数后,最后一个进程进入时,被阻塞,但是后面已经没有进程进入,无法触发之前的notify()释放。
解决方式:在代码段最后面加一个notify()用于释放最后一个进程,并且把wait()函数整体移动到输出语句之前,输出余额为100后再结束
最终版本:
class Account implements Runnable{
private int balance=1;
private int number=1;
@Override
public void run () {
while (number<100) {
synchronized (this){//synchronized用于确保线程安全问题
notify();//每次有一个新的线程经过就会释放当前正在阻塞的线程(前面一个线程)
try {
Thread.sleep(100);//增加线程等待时间,查看线程是否安全(但是有了synchronized后可以删除)
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
try {
wait();//进来的线程都要在这里阻塞一下,一直到下一个线程经过notify()才被释放
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(Thread.currentThread().getName()+"存款余额为:" + balance);
number++;
balance++;
notify();//释放最后一个线程
}
}
}
}
public class Bank {
public static void main(String[] args) {
Account account=new Account();
Thread t1=new Thread(account);
Thread t2=new Thread(account);
t1.setName("账号一");
t2.setName("账号二");
t1.start();
t2.start();
}
}
运行结果: