Java 多个线程共享同一对象的同步问题
Java Synchronization issue with muliple threads sharing same object
我目前正在 Java 学习同步。据我了解,同步实例方法获取其对象的锁。
我的程序是一个 50 个任务,然后每个任务都有一个线程。每个任务都会向从帐户 Class.
生成的帐户对象添加一分钱
账户 Class 有一个余额数据字段和一个同步的存款方法。这 50 个任务有一个帐户字段,该字段将指向相同的帐户对象(即共享帐户)。一旦调用运行,每个任务将调用account.deposit实例方法存入1个单位。
我预计余额将以 50 个单位结束。令人惊讶的是,该帐户有时会以 50 或其他余额 14、48、33 等结束。
class JavaStudy {
public static void main(String[] args){
for (int j = 0; j < 10; j++) {
Account account = new Account();
ExecutorService executorPool = Executors.newFixedThreadPool(50);
for (int i = 0; i < 50; i++) {
executorPool.execute(new DepositTask(account));
}
executorPool.shutdown();
while(!executorPool.isShutdown()){
}
System.out.println(account.getBalance());
}
}
}
存款任务class !
class DepositTask implements Runnable {
private Account account;
DepositTask(Account account){
this.account = account;
}
@Override
public void run() {
account.deposit(1);
}
}
帐户 Class !
class Account {
private int balance = 0;
synchronized public void deposit(int amount){
int balance = this.balance + amount;
this.balance = balance;
}
String getBalance(){
return "Balance: " + balance;
}
}
根据我的理解,据我所知,一旦任务访问,帐户应该被锁定 account.deposit(1); .其他任务应该无法访问它,因为它们共享同一个对象!不知怎的,这是行不通的,我得到以下结果,
Balance: 20
Balance: 47
Balance: 50
Balance: 42
Balance: 27
Balance: 24
Balance: 50
Balance: 29
Balance: 13
Balance: 12
Process finished with exit code 0
对正在发生的事情有什么想法吗?
我怀疑您不是在等待与关机不同的终止。这可能意味着并未执行所有任务。
executorPool.shutdown();
executorPool.awaitTermination(1, TimeUnit.MINUTES);
System.out.println(account.getBalance());
顺便说一句,在 Java 8 中,您可以使用
来简化它
Account account = new Account();
InStream.range(0, 50).parallel()
.forEach(i -> account.deposit(1));
System.out.println(account.getBalance());
我目前正在 Java 学习同步。据我了解,同步实例方法获取其对象的锁。
我的程序是一个 50 个任务,然后每个任务都有一个线程。每个任务都会向从帐户 Class.
生成的帐户对象添加一分钱账户 Class 有一个余额数据字段和一个同步的存款方法。这 50 个任务有一个帐户字段,该字段将指向相同的帐户对象(即共享帐户)。一旦调用运行,每个任务将调用account.deposit实例方法存入1个单位。
我预计余额将以 50 个单位结束。令人惊讶的是,该帐户有时会以 50 或其他余额 14、48、33 等结束。
class JavaStudy {
public static void main(String[] args){
for (int j = 0; j < 10; j++) {
Account account = new Account();
ExecutorService executorPool = Executors.newFixedThreadPool(50);
for (int i = 0; i < 50; i++) {
executorPool.execute(new DepositTask(account));
}
executorPool.shutdown();
while(!executorPool.isShutdown()){
}
System.out.println(account.getBalance());
}
}
}
存款任务class !
class DepositTask implements Runnable {
private Account account;
DepositTask(Account account){
this.account = account;
}
@Override
public void run() {
account.deposit(1);
}
}
帐户 Class !
class Account {
private int balance = 0;
synchronized public void deposit(int amount){
int balance = this.balance + amount;
this.balance = balance;
}
String getBalance(){
return "Balance: " + balance;
}
}
根据我的理解,据我所知,一旦任务访问,帐户应该被锁定 account.deposit(1); .其他任务应该无法访问它,因为它们共享同一个对象!不知怎的,这是行不通的,我得到以下结果,
Balance: 20
Balance: 47
Balance: 50
Balance: 42
Balance: 27
Balance: 24
Balance: 50
Balance: 29
Balance: 13
Balance: 12
Process finished with exit code 0
对正在发生的事情有什么想法吗?
我怀疑您不是在等待与关机不同的终止。这可能意味着并未执行所有任务。
executorPool.shutdown();
executorPool.awaitTermination(1, TimeUnit.MINUTES);
System.out.println(account.getBalance());
顺便说一句,在 Java 8 中,您可以使用
来简化它Account account = new Account();
InStream.range(0, 50).parallel()
.forEach(i -> account.deposit(1));
System.out.println(account.getBalance());