Как знать, закончились ли другие потоки?

Вы можете сделать деактивацию ViewEncapsulation. Посмотрите в следующем примере и для получения дополнительной информации прочитайте https://angular.io/guide/component-styles .

import { Component,ViewEncapsulation } from '@angular/core';

    @Component({
      selector: 'my-app',
      templateUrl: './app.component.html',
      styleUrls: [ './app.component.css' ],
    encapsulation: ViewEncapsulation.None
    })
    export class AppComponent  {
      name = 'Skycons';
    }

С наилучшими пожеланиями

121
задан Jeroen Mostert 28 April 2016 в 10:50
поделиться

7 ответов

Существует много способов, которыми можно сделать это:

  1. Используйте Thread.join () в Вашем основном потоке для ожидания блокирующимся способом каждого Потока для завершения, или
  2. Проверьте Thread.isAlive () способом опроса - обычно препятствовавшийся - для ожидания, пока каждый Поток не завершился, или
  3. Неортодоксальный, для каждого рассматриваемого Потока, setUncaughtExceptionHandler вызова для вызова метода в объекте и программы каждый Поток для выдачи неперехваченного исключения, когда это завершается, или
  4. Используйте блокировки или синхронизаторы или механизмы от java.util.concurrent, или
  5. Более православный, создайте слушателя в своем основном Потоке и затем программу каждый из Ваших Потоков, чтобы сказать слушателю, что они завершились.

Как реализовать Идею № 5? Ну, один путь состоит в том, чтобы сначала создать интерфейс:

public interface ThreadCompleteListener {
    void notifyOfThreadComplete(final Thread thread);
}

затем создайте следующий класс:

public abstract class NotifyingThread extends Thread {
  private final Set<ThreadCompleteListener> listeners
                   = new CopyOnWriteArraySet<ThreadCompleteListener>();
  public final void addListener(final ThreadCompleteListener listener) {
    listeners.add(listener);
  }
  public final void removeListener(final ThreadCompleteListener listener) {
    listeners.remove(listener);
  }
  private final void notifyListeners() {
    for (ThreadCompleteListener listener : listeners) {
      listener.notifyOfThreadComplete(this);
    }
  }
  @Override
  public final void run() {
    try {
      doRun();
    } finally {
      notifyListeners();
    }
  }
  public abstract void doRun();
}

и затем каждый из Ваших Потоков расширится NotifyingThread и вместо реализации run() это реализует doRun(). Таким образом, когда они завершаются, они автоматически уведомят любого ожидающего уведомления.

Наконец, в Вашем основном классе - тот, который запускает все Потоки (или по крайней мере объект, ожидающий уведомления) - изменяет тот класс к implement ThreadCompleteListener и сразу после создания каждого Потока добавляют себя к списку слушателей:

NotifyingThread thread1 = new OneOfYourThreads();
thread1.addListener(this); // add ourselves as a listener
thread1.start();           // Start the Thread

затем, поскольку каждый Поток выходит, Ваш notifyOfThreadComplete метод будет вызван с экземпляром Потока, который просто завершился (или отказал).

Обратите внимание, что лучше был бы к implements Runnable вместо extends Thread для NotifyingThread как расширяющий Поток обычно препятствуется в новом коде. Но я кодирую к Вашему вопросу. Если Вы изменяетесь NotifyingThread класс для реализации Runnable затем необходимо изменить часть кода, который управляет Потоками, который довольно прост, чтобы сделать.

225
ответ дан 24 November 2019 в 01:30
поделиться

Можно опросить экземпляр потока с getState (), который возвращает экземпляр Потока. Перечисление состояния с одним из следующих значений:

*  NEW
  A thread that has not yet started is in this state.
* RUNNABLE
  A thread executing in the Java virtual machine is in this state.
* BLOCKED
  A thread that is blocked waiting for a monitor lock is in this state.
* WAITING
  A thread that is waiting indefinitely for another thread to perform a particular action is in this state.
* TIMED_WAITING
  A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state.
* TERMINATED
  A thread that has exited is in this state.

Однако я думаю, что это был бы лучший дизайн, чтобы иметь основной поток, который ожидает этих 3 детей для окончания, ведущее устройство затем продолжило бы выполнение, когда другие 3 закончились.

4
ответ дан 24 November 2019 в 01:30
поделиться

Вы хотите ожидать их для окончания? Если так, используйте метод Соединения.

Существует также isAlive свойство, если Вы просто хотите проверить его.

4
ответ дан 24 November 2019 в 01:30
поделиться

Я предложил бы смотреть на javadoc для класса Потока.

У Вас есть несколько механизмов для управления потоком.

  • Ваш основной поток мог join() три потока последовательно, и затем не продолжились бы, пока все три не сделаны.

  • Опросите состояние потока порожденных потоков с промежутками.

  • Поместите все порожденные потоки в отдельное ThreadGroup и опрос activeCount() на ThreadGroup и ожидайте его для получения до 0.

  • Установите пользовательский обратный вызов или тип слушателя интерфейса для коммуникации межпотока.

Я уверен, что существует много других способов, которыми я все еще отсутствую.

2
ответ дан 24 November 2019 в 01:30
поделиться

Посмотрите на документацию Java для класса Потока. Можно проверить состояние потока. Если Вы помещаете три потока в членские переменные, то все три потока могут считать состояния друг друга.

Необходимо быть немного осторожными, тем не менее, потому что можно вызвать условия состязания между потоками. Просто старайтесь избегать сложной логики на основе состояния других потоков. Определенно избегайте нескольких потоков, пишущих в те же переменные.

0
ответ дан 24 November 2019 в 01:30
поделиться

Решение, использующее CyclicBarrier

public class Downloader {
  private CyclicBarrier barrier;
  private final static int NUMBER_OF_DOWNLOADING_THREADS;

  private DownloadingThread extends Thread {
    private final String url;
    public DownloadingThread(String url) {
      super();
      this.url = url;
    }
    @Override
    public void run() {
      barrier.await(); // label1
      download(url);
      barrier.await(); // label2
    }
  }
  public void startDownload() {
    // plus one for the main thread of execution
    barrier = new CyclicBarrier(NUMBER_OF_DOWNLOADING_THREADS + 1); // label0
    for (int i = 0; i < NUMBER_OF_DOWNLOADING_THREADS; i++) {
      new DownloadingThread("http://www.flickr.com/someUser/pic" + i + ".jpg").start();
    }
    barrier.await(); // label3
    displayMessage("Please wait...");
    barrier.await(); // label4
    displayMessage("Finished");
  }
}

label0 - создается циклический барьер с количеством сторон, равным количеству выполняемых потоков плюс один для основного потока выполнения (в котором startDownload () выполняется)

метка 1 - n-й поток загрузки входит в комнату ожидания

метка 3 - NUMBER_OF_DOWNLOADING_THREADS вошли в комнату ожидания. Основной поток выполнения освобождает их, чтобы они начали выполнять свои задания загрузки более или менее в то же время

метка 4 - основной поток выполнения входит в комнату ожидания. Это самая «сложная» часть кода для понимания. Неважно, какой поток во второй раз войдет в комнату ожидания. Важно, чтобы поток, входящий в комнату последним, гарантировал, что все остальные потоки загрузки завершили свои задания загрузки.

метка 2 - n-й поток DownloadingThread завершил свое задание загрузки и перешел в комнату ожидания. Если это последний, т. Е. В него уже вошли NUMBER_OF_DOWNLOADING_THREADS, включая основной поток выполнения, основной поток продолжит выполнение только после того, как все остальные потоки завершат загрузку.

13
ответ дан 24 November 2019 в 01:30
поделиться

Вы также можете использовать SwingWorker, который имеет встроенную поддержку изменения свойств. См. addPropertyChangeListener () или метод get () для примера прослушивателя изменения состояния.

0
ответ дан 24 November 2019 в 01:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: