java核心技术卷一第12章并发里面的问题
疑问:我只运行了一个Runnable(),为什么会创建这么多线程。
有个一个银行实体类:
```java
package concurrent.threads;
import java.util.Arrays;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Bank {
// 存储用户,就是金额
private final double[] accounts;
// 并发锁
private Lock bankLocks;
// 资金充足条件
private Condition sufficientFunds;
/**
* constructs of bank
* @param n 初始化账户的个数
* @param initialBalance
*/
public Bank(int n, double initialBalance) {
accounts = new double[n];
Arrays.fill(accounts, initialBalance);
bankLocks = new ReentrantLock();
sufficientFunds = bankLocks.newCondition();
}
/**
* transfer money from one account to another
* @param from
* @param to
* @param amount
*/
public void transfer(int from, int to, double amount) throws InterruptedException {
bankLocks.lock();
try {
if (accounts[from] < amount) {
// 资金不足,进入等待状态,并释放锁。
sufficientFunds.await();
}
System.out.print(Thread.currentThread());
accounts[from] -= amount;
System.out.printf(" %10.2f from %d to %d", amount, from, to);
accounts[to] += amount;
System.out.printf(" Total Balance: %10.2f%n", getTotalBalance());
// 完成转账,通知其他等待状态的线程,解除线程等待的阻塞。
sufficientFunds.signalAll();
} finally {
// 释放锁
bankLocks.unlock();
}
}
/**
* get the sum of all account balances
* @return
*/
public double getTotalBalance() {
bankLocks.lock();
try {
double sum = 0;
for (double account : accounts) {
sum += account;
}
return sum;
} finally {
bankLocks.unlock();
}
}
/**
* get the number of accounts in the bank
* @return
*/
public int size() {
return accounts.length;
}
}
使用多线程来进行转账:
package concurrent.threads;
public class UnsynchBankTest {
public static final int NACCOUNTS = 100;
public static final double INITIAL_BALANCE = 1000;
public static final double MAX_AMOUNT = 1000;
public static final int DELAY = 10;
public static void main(String[] args) {
Bank bank = new Bank(NACCOUNTS, INITIAL_BALANCE);
for (int i = 0; i < NACCOUNTS; i++) {
int fromAccount = i;
Runnable r = () -> {
try {
while (true) {
int toAccount = (int) (bank.size() * Math.random());
double amount = MAX_AMOUNT * Math.random();
bank.transfer(fromAccount, toAccount, amount);
Thread.sleep((long) (DELAY * Math.random()));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Thread t = new Thread(r);
t.start();
}
}
}
输出:
Thread[Thread-60,5,main] 124.70 from 60 to 83 Total Balance: 100000.00
Thread[Thread-74,5,main] 155.35 from 74 to 37 Total Balance: 100000.00
Thread[Thread-15,5,main] 819.57 from 15 to 79 Total Balance: 100000.00
Thread[Thread-73,5,main] 11.51 from 73 to 46 Total Balance: 100000.00
Thread[Thread-96,5,main] 442.61 from 96 to 28 Total Balance: 100000.00
Thread[Thread-97,5,main] 686.47 from 97 to 12 Total Balance: 100000.00
Thread[Thread-91,5,main] 53.28 from 91 to 29 Total Balance: 100000.00
Thread[Thread-75,5,main] 875.93 from 75 to 72 Total Balance: 100000.00
Thread[Thread-64,5,main] 218.91 from 64 to 42 Total Balance: 100000.00
Thread[Thread-28,5,main] 817.37 from 28 to 16 Total Balance: 100000.00
Thread[Thread-37,5,main] 761.64 from 37 to 65 Total Balance: 100000.00
Thread[Thread-78,5,main] 553.72 from 78 to 75 Total Balance: 100000.00
Thread[Thread-12,5,main] 121.35 from 12 to 16 Total Balance: 100000.00
可以看到程序创建了很多的线程。