dlage 2021-09-15 16:43 采纳率: 100%
浏览 29
已结题

一个Runnable开启了多个线程

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

可以看到程序创建了很多的线程。

  • 写回答

1条回答 默认 最新

  • 普通网友 2021-09-15 17:07
    关注

    首先,你的理解有出入,Runnable ,你不是只运行了一个,你是运行了好多个,

    代码在于 for循环里面,

            for (int i = 0; i < NACCOUNTS; i++) {
              Runnable r ...
    
            ....
          }
    

    相当于可以说,你运行【NACCOUNTS】个线程.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 9月23日
  • 已采纳回答 9月15日
  • 创建了问题 9月15日

悬赏问题

  • ¥20 sub地址DHCP问题
  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突
  • ¥15 超声波模块测距控制点灯,灯的闪烁很不稳定,经过调试发现测的距离偏大