我有一个带有两个同步方法的简单类。一种应提取现金,另一种应存款。
然后我有另一个带有内部类的主类。主类和内部类都实现了Runnable,其中主类运行“提取”方法,而内部类运行“存款”方法。
完成此操作后,我将创建两个线程来运行(即启动)单独的“ Runnable”类中的单独方法。
具有同步方法的类具有以下方法:
package test;
public class ThreadClass {
int amount = 10;
synchronized void withdraw(int amount) {
System.out.println("going to withdraw...");
if(this.amount < amount) {
System.out.println("Less balance..");
try {
wait();
}
catch(Exception e) {
e.printStackTrace();
}
}
this.amount+=amount;
System.out.println("withdrawal completed");
}
synchronized void deposit(int amount) {
System.out.println("going to deposit...");
this.amount+=amount;
System.out.println("deposit completed");
notify();
}
}
,负责实现Runnable并运行示例应用程序的类如下所示:
package test;
public class ThreadTest implements Runnable {
@Override
public void run() {
ThreadClass withDraw = new ThreadClass();
withDraw.withdraw(20);
}
class Threadtest2 implements Runnable{
@Override
public void run() {
ThreadClass t10 = new ThreadClass();
t10.deposit(60);
}
}
public static void main(String[] args) throws InterruptedException {
ThreadTest tester = new ThreadTest();
ThreadTest.Threadtest2 tester2 = tester.new Threadtest2();
Thread t1 = new Thread(tester);
t1.start();
Thread t2 = new Thread(tester2);
t2.start();
}
}
因此,当我运行该程序时,我期望deposit方法中的notify()调用应通知withdraw()方法,以便最后一行也得到执行,即
this.amount+=amount;
System.out.println("withdrawal completed");
..但是应用程序一直在运行,并且从未到达该行,因此我必须手动终止它。这不是正确的方法吗?
答案 0 :(得分:3)
synchronized
方法在对象的当前实例上同步。因此,wait()
和notify()
应该在完全相同的对象上调用。但是,您创建了ThreadClass
对象的两个不同实例,因此您在不同的对象上调用wait()
和notify()
。
您应该创建ThreadClass
的单个实例,并将其传递给线程,例如通过构造函数:
public class ThreadTest implements Runnable {
private ThreadClass account;
public ThreadTest(ThreadClass account) {
this.account = account;
}
@Override
public void run() {
account.withdraw(20);
}
}
class Threadtest2 implements Runnable{
private ThreadClass account;
public Threadtest2(ThreadClass account) {
this.account = account;
}
@Override
public void run() {
account.deposit(60);
}
}
然后像这样初始化它们:
ThreadClass account = new ThreadClass();
ThreadTest tester = new ThreadTest(account);
ThreadTest.Threadtest2 tester2 = tester.new Threadtest2(account);
还请注意,在wait()
之后,如果存款额不足,则条件this.amount < amount
仍然适用。因此,您应该检查金额并循环调用wait()
,直到满足此条件为止。