Обновление Swift 4 по сравнению со Swift 3
Swift 4 устраняет необходимость в массиве символов в String. Это означает, что вы можете напрямую вызывать count
для строки без предварительного получения массива символов.
"hello".count // 5
В то время как в swift 3 вам нужно будет получить массив символов и затем подсчитать элемент в этом массиве. Обратите внимание, что этот следующий метод все еще доступен в swift 4.0, так как вы все еще можете вызвать characters
для доступа к массиву символов данной строки
"hello".characters.count // 5
Swift 4.0 также принимает Unicode 9 и теперь может интерпретировать кластеры графем. Например, если вы рассчитываете на смайликов, вы получите 1, а в Swift 3.0 вы можете получить больше, чем 1.
"
Используйте take () вместо poll () и поместите () вместо add (). Тогда семафор полностью избыточен, так что вы можете просто избавиться от него. Но да, выглядит неплохо.
Возможно, вам стоит проверить, существуют ли объекты, это единственное, что у меня есть .
Edit: Я не очень внимательно читал код. Поэтому я немного отредактировал пост. : (
Как уже указывалось, одной ограниченной BlockingQueue было бы достаточно. Например, следующий код сделает то, что вы хотите:
import java.util.Collection;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public final class Pool<T> {
private final BlockingQueue<T> objects;
public Pool(Collection<? extends T> objects) {
this.objects = new ArrayBlockingQueue<T>(objects.size(), false, objects);
}
public T borrow() throws InterruptedException {
return this.objects.take();
}
public void giveBack(T object) throws InterruptedException {
this.objects.put(object);
}
}
Кроме того, вы можете рассмотреть возможность поддержки синхронизированной версии заимствования () с помощью BlockingQueue.poll ().
Если у вас не было очереди с ограничениями на блокировку структуры данных, то вы можете наложить семафор поверх любой структуры данных, чтобы создать потокобезопасное и связанное поведение.
Ничего не стоит, если ArrayBlockingQueue создает объект, когда вы берете из него запись. Таким образом, ваш пул на самом деле не будет сохранять объекты. Это может помочь, только если ваши объекты дороги в создании.
Несколько модифицированный пример Сджли; возможность создания дорогих объектов под заказ. В моем случае не требовалось никаких средств блокировки, поэтому я заменил их на неблокирующий тип очереди. В качестве преимущества нет необходимости иметь дело с InterruptedExceptions.
import java.util.Collection;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
public abstract class ObjectPool<T> {
private final Queue<T> objects;
public ObjectPool() {
this.objects = new ConcurrentLinkedQueue<T>();
}
public ObjectPool(Collection<? extends T> objects) {
this.objects = new ConcurrentLinkedQueue<T>(objects);
}
public abstract T createExpensiveObject();
public T borrow() {
T t;
if ((t = objects.poll()) == null) {
t = createExpensiveObject();
}
return t;
}
public void giveBack(T object) {
this.objects.offer(object); // no point to wait for free space, just return
}
}
Может быть, вместо очереди использовать стек? Это дает шанс получить объект, который все еще находится в кэше процессора.