Исполнители Java: ожидайте завершения задачи. [дубликат]

Я должен был реализовать пользовательскую-initated функциональность SMS на нашем веб-сайте недавно и нашел сервис www.dotgo.com полезным. Это свободно... похож на него, был создан несколькими PhD как своего рода своего рода платформа обмена сообщениями не сохраняющая состояние (думайте модель ответа запроса HTTP).

Для получения это работающий Вас настроило "index.crml" файл (подобный index.html, php, и т.д.). Наши смотрят как это (извините все помещение всего этого на одной одной строке... имеющей некоторые проблемы, заставляющие это отображаться иначе):

<?xml version="1.0" encoding="UTF-8"?><cmrl xmlns:dotgo="http://dotgo.com/cmrl/1.0"><match pattern="*"><engine href="http://www.bulbstorm.com/sms/flashbulb.php"/></match></cmrl>

На нашем сайте индексный файл в свою очередь ссылается на/sms/flashbulb.php файл, который (исключая открытие и закрытие тегов PHP) похож на это:

$wordArray = explode(' ',$_REQUEST['sys_argument']);
$username = strip_tags($wordArray[0]);
$messageBody = str_replace($username.' ', '', $_REQUEST['sys_argument']);
require_once 'Database.php';
$dbh = new Database('bulbstorm');
$args = array($username, $messageBody);
$dbh->execMysqlProc('uspAddFlashbulb', $args);
print "<message><content>Bulb received and saved to your account</content></message>";

Так или иначе я только включаю код для предоставления некоторого смысла того, как платформа функционирует и как мало кода там должно записать для получения чего-то функционального.

Существуют некоторые ограничения. Передовое существо, что все - пользователь-initated. Таким образом, если Вы, прежде всего, надеетесь отправлять исходящие сообщения, которым не предшествует Ваш пользователь, отправляющий сообщение в Ваш сайт для "получения" ответного сообщения затем, это, вероятно, не, что Вы хотите. Работавший для того, что мы делали все же. Один из основателей даже лично ответил на отправленный по электронной почте вопрос и был очень услужлив.

Одной из функций, которые мы еще не использовали, но рассмотрели, является их функциональность подписки..., где пользователи могут настроить его так, чтобы dotgo система периодически опрашивала страницу на Вашем сайте, отправляя сообщение SMS на их телефон на расписание, которое указывает пользователь. Снова, я не взял его, что далеко, но думал, что это было интересно.

15
задан Chan 23 April 2013 в 18:13
поделиться

5 ответов

Служба ExecutorService дает вам механизм для одновременного выполнения нескольких задач и получения обратно коллекции объектов Future (представляющих асинхронное вычисление задачи) .

Collection<Callable<?>> tasks = new LinkedList<Callable<?>>();
//populate tasks
for (Future<?> f : executorService.invokeAll(tasks)) { //invokeAll() blocks until ALL tasks submitted to executor complete
    f.get(); 
}

Если у вас есть Runnable s вместо Callable s, вы можете легко превратить Runnable в Callable используя метод:

Callable<?> c = Executors.callable(runnable);
21
ответ дан 1 December 2019 в 00:16
поделиться

Вместо того, чтобы отправлять Runnable или Callable s напрямую Executor и сохранять соответствующие возвращаемые значения Future я бы рекомендовал использовать реализацию CompletionService для получения каждого Future , когда оно завершится . Этот подход отделяет производство задач от потребления завершенных задач, что позволяет, например, создавать новые задачи в потоке-производителе в течение определенного периода времени.

Collection<Callable<Result>> workItems = ...
ExecutorService executor = Executors.newSingleThreadExecutor();
CompletionService<Result> compService = new ExecutorCompletionService<Result>(executor);

// Add work items to Executor.
for (Callable<Result> workItem : workItems) {
  compService.submit(workItem);
}

// Consume results as they complete (this would typically occur on a different thread).
for (int i=0; i<workItems.size(); ++i) {
  Future<Result> fut = compService.take(); // Will block until a result is available.
  Result result = fut.get(); // Extract result; this will not block.
}
14
ответ дан 1 December 2019 в 00:16
поделиться

Не могли бы вы предложить мне путеводитель / книгу о исполнители java ??

Я могу ответить на эту часть:

Java Concurrency in Practice Брайан Гетц (с Тимом Пайерлсом, Джошуа Блох , Джозефом Баубиром, Дэвидом Холмсом и Дугом) Lea ), скорее всего, ваш лучший выбор.

Это касается не только исполнителей, но вместо этого охватывает пакет java.util.concurrent в целом, а также базовый концепции и методы параллелизма, а также некоторые дополнительные темы, такие как модель памяти Java.

14
ответ дан 1 December 2019 в 00:16
поделиться

При отправке в службу-исполнитель вы получите Возвращение будущего объекта .

Сохраните эти объекты в коллекции, а затем вызовите get () для каждого по очереди. get () блокируется до тех пор, пока базовое задание не завершится, поэтому в результате вызов get () для каждого из них завершится после завершения всех базовых заданий.

например

Collection<Future> futures = ...
for (Future f : futures) {
   Object result = f.get();
   // maybe do something with the result. This could be a
   // genericised Future<T>
}
System.out.println("Tasks completed");

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

2
ответ дан 1 December 2019 в 00:16
поделиться
ExecutorService executor = ...
//submit tasks
executor.shutdown(); // previously submitted tasks are executed, 
                     // but no new tasks will be accepted
while(!executor.awaitTermination(1, TimeUnit.SECONDS))
    ;

Нет простого способа делать то, что вы хотите, без создания настраиваемой ExecutorService.

1
ответ дан 1 December 2019 в 00:16
поделиться