在这个多线程java应用程序中,只有一个线程像顺序程序一样运行?
抱歉,描述太长了。如果时间太长,请告诉我如何改进 我正在学习Java并发性。这是我试图编写的一个场景 母亲和孩子共用一个银行账户。母子线程是两个独立的线程,从程序的主线程开始 在两者的run()中,它们执行多个银行交易。为简单起见,孩子只做取款交易,母亲只做存款交易。每个事务也是一个单独的线程。孩子/母亲必须等到一个事务完成后才能开始下一个事务。(等待/notifyAll用于此操作) 如果取款任务尝试取款,但余额不足(余额最初为0),则线程将进入while循环,等待余额大于取款金额 母亲在每次存款任务之间睡眠500毫秒 我所期望的 由于母亲在每次存款之间睡觉,而孩子在取款期间不睡觉,因此可以保证孩子的任务在循环时输入在这个多线程java应用程序中,只有一个线程像顺序程序一样运行?,java,multithreading,concurrency,Java,Multithreading,Concurrency,抱歉,描述太长了。如果时间太长,请告诉我如何改进 我正在学习Java并发性。这是我试图编写的一个场景 母亲和孩子共用一个银行账户。母子线程是两个独立的线程,从程序的主线程开始 在两者的run()中,它们执行多个银行交易。为简单起见,孩子只做取款交易,母亲只做存款交易。每个事务也是一个单独的线程。孩子/母亲必须等到一个事务完成后才能开始下一个事务。(等待/notifyAll用于此操作) 如果取款任务尝试取款,但余额不足(余额最初为0),则线程将进入while循环,等待余额大于取款金额 母亲在每次存
资金不足。然而,由于母亲是一个单独的线程,等待500毫秒后,它将存款一些钱。然后孩子的取款任务线程会注意到这一点,退出while循环并完成事务
发生了什么
孩子进入一个无限循环,试图退出。母亲的线不会沉积
我有一种预感,这与wait()有关。当我从child调用task.wait()时,它正在等待task类的这个特定实例调用notify()对吗?不是任务类的所有实例
对母亲和孩子都是如此。我得到了相同的输出。母线程和子线程正在等待相同的任务
对象,因此如果调用任务。notifyAll()
,它们将被唤醒。然而,事实并非如此。当存款更多时,账户
会调用notifyAll
这个实现的主要问题是任务是一个单独的线程。如果您仍然希望保持这种状态,那么您可以这样做:
首先:Account.draw使用睡眠等待。相反,它应该使用wait()
,这样当Account.deposit
调用notifyAll
时,它就可以醒来了
您的母亲
和孩子
线程可以等待任务
,但是任务
必须通知他们。因此,在任务结束时,运行您应该调用notifyAll
来唤醒等待任务的所有线程
实际上,您正在使用三个线程来运行一个顺序任务。除了其他问题外,System.out.println
在内部是同步的。您好,按照您的建议执行了。仍然得到同样的回应。更新了有问题的代码。我想我知道出了什么问题。我改变了答案。母亲和孩子仍然应该等待任务,但任务必须等待。我现在明白了。谢谢:)
public class Test {
public static void main(String[] args) {
Account account = new Account();
new Child("Bob", account).start();
new Mother("mary", account).start();
}
}
class Child extends Thread {
String name;
Account account;
public Child(String name, Account account) {
super("Child");
this.name = name;
this.account = account;
}
private void transaction(int val, TaskType taskType) {
Task task = new Task(account, taskType, val);
task.start();
synchronized (task) {
try {
task.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
public void run() {
this.transaction(100, TaskType.WITHDRAW);
System.out.println("100 WITHDRAW");
this.transaction(150, TaskType.WITHDRAW);
System.out.println("150 WITHDRAW");
this.transaction(200, TaskType.WITHDRAW);
System.out.println("200 WITHDRAW");
this.transaction(500, TaskType.WITHDRAW);
System.out.println("500 WITHDRAW");
}
}
class Mother extends Thread {
String name;
Account account;
public Mother(String name, Account account) {
super("Mother");
this.name = name;
this.account = account;
}
private void transaction(int val, TaskType taskType) {
Task task = new Task(account, taskType, val);
task.start();
synchronized (task) {
try {
task.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
public void run() {
this.transaction(100, TaskType.DEPOSIT);
System.out.println("100 DEPOSIT");
try {
Thread.sleep(600);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.transaction(150, TaskType.DEPOSIT);
try {
Thread.sleep(600);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("150 DEPOSIT");
this.transaction(200, TaskType.DEPOSIT);
try {
Thread.sleep(600);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("200 DEPOSIT");
this.transaction(500, TaskType.DEPOSIT);
try {
Thread.sleep(600);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("500 DEPOSIT");
}
}
class Task extends Thread {
private static int id = 0;
Account account;
TaskType taskType;
int val;
public Task(Account account, TaskType taskType, int val) {
super("Task");
this.account = account;
this.taskType = taskType;
this.val = val;
}
@Override
public void run() {
switch (taskType) {
case WITHDRAW:
account.withdraw(val, id);
break;
case DEPOSIT:
account.deposit(val, id);
break;
}
id += 1;
}
}
class Account {
int balance = 0;
public synchronized void deposit(int val, int id) {
this.balance += val;
this.notifyAll();
}
public synchronized void withdraw(int val, int id) {
while (this.balance < val) {
System.out.println("Funds insufficient waiting..." + id);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.balance -= val;
System.out.println("Withdrawal successful " + id);
this.notifyAll();
}
}
enum TaskType {
DEPOSIT,
WITHDRAW
}
private void transaction(int val, TaskType taskType) {
Task task = new Task(account, taskType, val);
task.start();
synchronized (account) {
try {
account.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}