Недавно я наткнулся на этот вопрос: скажем, 3 пользовательских потока, и необходимо реализовать очередь без блокировки (не может использовать синхронизация ), чтобы не потреблял потокзаблокирован.Предположим, что очередь уже содержит данные.
Я немного подумал об этом и натолкнулся на Атомные операции, которые при правильном использовании могут помочь.Моя реализация, как показано ниже.Поскольку данные уже находятся в очереди, я не реализовал метод enqueue
и не заполнил массив внутри конструктора.
public class SPMCQueue {
private AtomicInteger index = new AtomicInteger(0);
public int[] arr;
public SPMCQueue(int size) {
arr = IntStream.range(0, size).toArray();
}
public Integer dequeue() {
Integer ret = null;
int x = index.getAndIncrement();
if (x < arr.length) {
ret = arr[x];
System.out.println(arr[x] + " by " + Thread.currentThread().getName());
}
else {
throw new RuntimeException("Queue is empty");
}
return ret;
}
}
class QueueTest {
public static void main(String[] args) {
SPMCQueueq = new SPMCQueue(40);
Runnable t1 = () -> {
try {
while (true) {
q.dequeue();
}
}catch(Exception e) {
}
};
Runnable t2 = () -> {
try {
while(true) { q.dequeue(); }
}catch(Exception e) {
}
};
Runnable r3 = () -> {
try {
while(true) { q.dequeue(); }
} catch (Exception e) {
// TODO Auto-generated catch block
//e.printStackTrace();
}
};
Thread thread1 = new Thread(t1);
Thread thread2 = new Thread(t2);
Thread thread3 = new Thread(r3);
thread1.start();
thread2.start();
thread3.start();
}
}
Я выполнил вышеуказанную программу, и результат показывает, что все 3 потребителя потребляютданные хотя и не в порядке, и некоторые потоки потребляют больше данных, чем другие потоки, но я не вижу, чтобы какие-либо данные появлялись несколько раз в o / p.
У меня есть следующие вопросы:
Есть ли какие-либо проблемы в приведенной выше реализации?
Каковы другие способыреализовать очередь потребителей без блокировки?