Возвращает ли метод thread.start () для нового потока немедленное возвращение к текущему потоку? - PullRequest
0 голосов
/ 22 февраля 2020

Я читаю книгу Core java Кей С. Хорстманн. Я запутался с этим кодом в разделе параллелизма. Мы создаем новую нить и передаем ей задачу Runnable, я понимаю, до этого. Меня смущает то, что мы вызываем метод start() для этих новых потоков за другим. Мой вопрос заключается в том, что когда первый вызов метода start() возвращается к методу main(). Это после того, как новый поток завершил свою задачу, или он возвращается, когда этот новый поток выполняет задачу?

import java.util.Arrays;

public class Main{
  public static final int DELAY = 10;
  public static final int STEPS = 100;
  public static final double MAX_AMOUNT = 1000;

  public static void main(String[] args)  {

    var bank = new Bank(4, 100000);
    Runnable task1 = () -> {
    try {

    for (int i = 0; i < STEPS; i++){

      double amount = MAX_AMOUNT * Math.random();
      bank.transfer(0, 1, amount);
      Thread.sleep((int) (DELAY * Math.random()));

    }

    }catch (InterruptedException e) {
    }

    };

    Runnable task2 = () ->{
    try{

    for (int i = 0; i < STEPS; i++){

      double amount = MAX_AMOUNT * Math.random();
      bank.transfer(2, 3, amount);
      Thread.sleep((int) (DELAY * Math.random()));

    }

    }
    catch (InterruptedException e){
    }

    };

    new Thread(task1).start();
    new Thread(task2).start();

  }

}

class Bank{

  private final double[] accounts;

  /**
   * Constructs the bank.
   * @param n the number of accounts
   * @param initialBalance the initial balance for each account
   *
   **/

  public Bank(int n, double initialBalance){

    accounts = new double[n];
    Arrays.fill(accounts, initialBalance);

   }

   /**
    * Transfers money from one account to another.
    * @param from the account to transfer from
    * @param to the account to transfer to 27
    * @param amount the amount to transfer 28
    **/

   public void transfer(int from, int to, double amount){

     if (accounts[from] < amount) return;
     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());

   }
   /**
    * Gets the sum of all account balances.
    * @return the total balance 42
    **/

   public double getTotalBalance(){

     double sum = 0;
     for (double a : accounts)
       sum += a;
     return sum;

   }

   /**
    * Gets the number of accounts in the bank.
    * * @return the number of accounts 56
    **/

   public int size(){

     return accounts.length;

   }

}

Ответы [ 3 ]

1 голос
/ 22 февраля 2020

Метод запуска возвращается немедленно, и основной поток продолжает работать.

Вы можете увидеть, как это происходит с этой маленькой прогой:

import java.time.Duration;
import java.time.ZonedDateTime;

public class Runner {

    public static void main(final String[] args) throws Exception {

        final Runnable runner = () -> {
            System.out.println(ZonedDateTime.now() + " " + Thread.currentThread().getName() + " Running...");

            sleep(Duration.ofSeconds(9));

            System.out.println(ZonedDateTime.now() + " " + Thread.currentThread().getName() + " Done.");
        };

        System    .out.println(ZonedDateTime.now() + " " + Thread.currentThread().getName() + " starting Thread 1...");
        new Thread(runner).start();

        System    .out.println(ZonedDateTime.now() + " " + Thread.currentThread().getName() + " starting Thread 2...");
        new Thread(runner).start();

        sleep(Duration.ofSeconds(3));

        System    .out.println(ZonedDateTime.now() + " " + Thread.currentThread().getName() + " done.");
    }

    private static void sleep(final Duration duration) {
        try {
            Thread.sleep(duration.toMillis());
        }
        catch (final InterruptedException e) {}
    }
}
0 голосов
/ 24 марта 2020

Да, он возвращается, когда обрабатывает новый метод run для нового потока. Затем пул потоков обрабатывает поток управления потоками. См. Потоки и параллелизм в java

0 голосов
/ 22 февраля 2020

Запустите метод fini sh сразу после создания нового потока. Результатом метода start являются два потока, которые работают одновременно: текущий поток (который возвращает вызов метода start) и другой поток (который выполняет метод run).

Метод start () внутренне вызывает метод run () интерфейса Runnable для выполнения кода, указанного в методе run (), в отдельном потоке.

Выполнение начального потока в основном потоке аналогично любому другому выражению. Если вы хотите дождаться окончания потока sh, вы должны использовать для него метод join:

Thread t1 = new Thread(task1).start();
t1.join();

Поток завершает свое выполнение, когда его метод запуска завершается sh.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...