Я думаю, что вы имеете в виду неблокирующее и реентерабельное.
edit: (заменяет мой оригинал, потому что это намного лучше)
Только что пришла в голову потоковая опция, которая на самом деле довольно производительная (по крайней мере, более производительная, чем ваш оригинал). Если вы создали слабую хэш-карту с объектом потока в качестве «Ключа» и «Значения», поместите объект с возможностью создания серии, скажем, 1000 чисел из определенного диапазона.
Таким образом, вы назначаете каждому потоку свой собственный диапазон номеров 1000, из которого он будет выделяться. Когда у объекта заканчиваются числа, пусть он вернет недопустимое число (0?), И вы будете знать, что вам нужно выделить новый диапазон этому объекту.
Не было бы никакой синхронизации где-либо (edit: whoops, было немного неправильно. См. Ниже), слабая хеш-карта автоматически освобождала нити, которые были уничтожены (без специального обслуживания), а самой медленной частью был бы поиск одного хеш нити, которая на самом деле очень быстро.
получить текущий запущенный поток с:
Thread currThread=Thread.getCurrentThread();
Также я могу ошибаться, и вам просто нужно синхронизировать метод, тогда это будет работать:
int n=-1;
synchronized int getNegativeNumber() {
return n--;
}
Я пошел дальше и написал это (иногда этот материал застревает в моей голове, пока я не сделаю это, и, пока я это делал, я мог бы также опубликовать это). Не проверено и все, но я почти уверен, что оно должно быть близко, если не прямо из коробки. Всего один класс с одним статическим методом для вызова уникального отрицательного числа. (О, и мне нужна была некоторая синхронизация, но она будет использоваться только в .001% времени).
Хотелось бы, чтобы был способ создать связанный кодовый блок вместо встроенного, как это, не уходя с сайта - извините за длину.
package test;
import java.util.WeakHashMap;
public class GenNumber {
// Static implementation goes first.
private static int next = -1;
private static final int range = 1000;
private static WeakHashMap<Thread, GenNumber> threads = new WeakHashMap<Thread, GenNumber>();
/**
* Generate a unique random number quickly without blocking
*
* @return the random number < 0
*/
public static int getUniqueNumber() {
Thread current = Thread.currentThread();
int next = 0;
// Have to synchronize some, but let's get the very
// common scenario out of the way first without any
// synchronization. This will be very fast, and will
// be the case 99.9% of the time (as long as range=1000)
GenNumber gn = threads.get(current);
if (gn != null) {
next = gn.getNext();
if (next != 0)
return next;
}
// Either the thread wasn't found, or the range was
// used up. Do the rest in a synchronized block.
// The three lines tagged with the comment "*" have
// the potential to collide if this wasn't synchronized.
synchronized (threads) {
if (gn == null) {
gn = new GenNumber(next -= range); // *
threads.put(current, gn); // *
return gn.getNext(); // can't fail this time
}
// now we know the range has run out
gn.setStart(next -= range); // *
return gn.getNext();
}
}
// Instance implementation (all private, nobody needs to see this)
private int start;
private int count;
private GenNumber(int start) {
setStart(start);
}
private int getNext() {
if (count < range)
return start - count;
return 0;
}
private GenNumber setStart(int start) {
this.start = start;
return this;
}
}
Меня просто поразило, что вместо одного большого синхронизированного блока можно заменить 2 очень маленьких, синхронизированных на разных объектах, один для "+ = count" и один для .put (). Если коллизии все еще замедляют вас, это может помочь (хотя, если коллизии все еще замедляют вас (ДЕЙСТВИТЕЛЬНО ???), вам лучше обслужить, просто повысив счет.