Если вы знакомы с библиотеками Java Concurrent, использование класса AsyncScalr действительно просто;если вы не знакомы с новыми параллельными библиотеками, суть в следующем:
- Вызовите метод API, который выполняет некоторую работу в неизвестном месте в будущем;вызов метода возвращает Future , который оборачивает фактическую работу.
- Исходный вызов API фактически ставит работу в очередь;если он не занят, он, скорее всего, выполнит работу сразу, но если он занят и очередь огромна, работа может занять некоторое время (в этом случае «работа» - это масштабированиеimage).
- Вызывающий код (ваш код), который хочет получить результат, может продолжать работать до тех пор, пока Future.isDone () не вернет true, чтобы указать, что работа завершена ИЛИ вызывающий код можетпросто блокируйте, пока операция не будет выполнена, вызывая: Future.get () - этот метод возвращает результат работы, в данном случае BufferedImage, который представляет масштабированный результат.
Код буквально в итоге выглядит так:
// Block until result is done
BufferedImage result = AsyncScalr.resize(origImage, 125).get();
Разница между этим кодом и использованием класса Scalr напрямую заключается в том, что в многопоточных системах, если вы вызываете Scalr.resize () (или любой из операций с изображениями) из ВСЕХ ваших потоков, каждый из этих потоков начнет дорогостоящую операцию с изображениями, загружая ваш ЦП параллельной работой и замедляя систему доcrawl (отключение других процессов, запущенных на нем, таких как БД или веб-сервер).
Используя AsyncScalr класс , вы можете безопасно вызывать AsyncScalr.resize (или любую другую операцию) с любого номерапотоков и никогда не беспокоиться о том, чтобы загружать хост-систему работой; AsyncScalr.THREAD_COUNT определяет, сколько одновременных заданий может выполняться одновременно;Обычно вы хотите установить это число ядер на хост-машине или меньше количества ядер, если на хост-машине также размещены другие важные сервисы, такие как база данных или веб-сервер (чтобы вы не заглушали другиеобрабатывает, когда масштабирование занято).
Вы можете установить это значение потока в командной строке во время запуска приложения с помощью системного свойства "imgscalr.async.threadCount";по умолчанию это «2», но вы можете установить его на «1», если вы беспокоитесь о том, что в системе слишком мало памяти.
В качестве альтернативы, если у вас есть работа, которую может выполнять ваш поток, пока вы ждетеВ результате вы можете сделать что-то вроде этого, чтобы действительно эффективно использовать асинхронное программирование:
// Queue up the scaling operation (or any other op)
Future<BufferedImage> result = AsyncScalr.resize(origImage, 125);
/*
* You can do other work here that doesn't need 'result', like making
* DB calls, cleaning up temp files or anything else you might need to
* do.
*/
// Now we are all done and need the resulting image, so we wait for it.
BufferedImage scaledImage = result.get();
// Do something with the image...
Если у вас было значительное количество других работ, которые вы могли бы выполнять, ожидая, пока изображениемасштабироваться, вы можете просто зациклить result.isDone()
и продолжать работать, пока операция масштабирования не будет завершена;но если у вас есть только определенный / конкретный объем работы, не нужно зацикливаться на isDone, просто сделайте эту работу, затем вызовите Future.get()
, чтобы получить результат (или заблокируйте его, пока он не будет готов).
Надеюсь, это поможет!