Вот сам код:
import net.jcip.annotations.GuardedBy;
import net.jcip.annotations.ThreadSafe;
import java.util.LinkedList;
import java.util.Queue;
/**
* Класс состоит их двух методов:
* Первый добавляет элементы в коллекцию если очередь не полна.
* Второй извлекает элементы из коллекции если очередь не полна.
*/
@ThreadSafe
public class SimpleBlockingQueue<E> {
@GuardedBy("this")
private Queue<E> queue = new LinkedList<>();
@GuardedBy("this")
private E size;
public SimpleBlockingQueue(E size) {
this.size = size;
}
public synchronized void offer(E value) {
if (queue.size() > (int) size) {
try {
wait();
} catch (InterruptedException e) {
System.out.println("Исключения типа InterruptedException перехвачено");
}
} else {
queue.offer(value);
notify();
}
}
public synchronized E poll() {
E result = null;
if (queue.isEmpty()) {
try {
wait();
} catch (InterruptedException e) {
System.out.println("Исключения типа InterruptedException перехвачено");
}
} else {
result = queue.poll();
notify();
}
return result;
}
public synchronized int getSizeQueue() {
return queue.size();
}
}
Вот код теста:
import org.junit.Before;
import org.junit.Test;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.*;
public class SimpleBlockingQueueTest {
SimpleBlockingQueue<Integer> blocking = new SimpleBlockingQueue<>(7);
private Thread producer;
private Thread consumer;
@Before
public void when() {
producer = new Thread() {
@Override
public void run() {
int i = 0;
while (i < 6) {
blocking.offer(i);
i++;
}
}
};
consumer = new Thread() {
@Override
public void run() {
int i = 0;
while (i < 6) {
assertThat(blocking.getSizeQueue(), is(6 - i));
assertThat(blocking.poll(), is(i));
assertThat(blocking.getSizeQueue(), is(6 - 1 - i));
i++;
}
}
};
}
@Test
public void start() throws InterruptedException {
producer.start();
consumer.start();
producer.join();
consumer.join();
}
}
Иногда проходит тест, а иногда бывают ошибки:
Судя по всему тест проверяет только, что элементы были добавлены в нужном порядке.
Проблема связана с тем, что нет гарантии, что producer
выполнится раньше consumer
. В запусках, которые не проходят, consumer
выполняется первым и не обнаруживает элементов в очереди.
Чтобы исправить можете сначала дождаться пока producer
завершит работу:
producer.start();
producer.join();
//и после запускаем consumer
consumer.start();
consumer.join();
Насколько это решение допустимо зависит от поставленной перед тестом задачи. Если просто нужно протестировать порядок элементов в очереди, то этот вариант подойдет, но в этом случае можно обойтись и без потоков. Если же нужно протестировать параллельную работу, то этот вариант не подойдет, нужно будет либо настраивать синхронизацию потоков, либо строить логику получения значения чтобы consumer
дожидался следующего значения, перед тем как его сверять.
Имеется игровой сервер, который использует hibernate для работы с базой данных, спустя n-времени, сервер просто выдает такую ошибку:
Не открывается почему то меню при нажатии на гамбургерБраузер пишет: "ReferenceError: toggleMenu is not defined"
Подскажите, как привязать событие нажатия на кнопку button к кнопке на клавиатуре?
В общем сделал слайдер, нормально работает(slick slider), сунул всё это дело в табы и при переключении по ним он как бы есть(но его как бы нет)Что...