Skip to content

Instantly share code, notes, and snippets.

@findli
Created June 3, 2019 08:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save findli/dcdc59a9fa9701a5ab67b3acee79d676 to your computer and use it in GitHub Desktop.
Save findli/dcdc59a9fa9701a5ab67b3acee79d676 to your computer and use it in GitHub Desktop.
CandyServiceBase test case
package dz.cypix.ru;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Random;
import java.util.concurrent.*;
/*
* <p>
* Test case by Ian Burtovoy
* skype yanchik366
* email burtovoy.ian@gmail.com
* <p>
Необходимо реализовать имплементацию класса CandyServiceBase - многопоточного сервиса по пожиранию конфет, со следующими условиями:
1. При инциализации сервиса пожирания, ему передается уже готовый список доступных пожирателей конфет; // runnable
2. Время пожирания конфет одним пожирателем может занимать некоторое время;// thread.sleep(rand 1000)
3. Конфеты должны пожираться паралельно максимально доступным количеством пожирателей;// 1 in executorservice
4. Один пожитратель может есть только одну конфету в момент времени;// на вкус blocking queue
5. У конфет есть вкус(можно рассматривать как некий конечный enum или справочник вкусов определяемый по его id);
6. Одновременно могут пожираться только разные вкусы конфет, два разных пожирателя не должны одновременно кушать конфеты с одинаковым вкусом;// while random(length tastes) eat
7. Фактом съедения конфеты является передача пожирателю конфеты в метод ICandyEater.eat и ожидание его выполнения;
8. Реализация интерфейсов самих конфет и пожирателей не требуется;
9. CandyServiceBase.addCandy должен максимально быстро возращать управление в вызвавший его код, не должно быть блокировки;// blockingqueue
10. Требуется соблюсти насколько это возможно порядок съедения конфет в порядке их поступления для конфет одного вкуса;// blockingqueuelist
11. За основу взять следующий код:
*/
public class App {
/**
* Конфета, имеет вкус, можно съесть
*/
public interface ICandy {
/**
* Получить вкус конфеты
*/
int getCandyFlavour();
}
/**
* Интерфейс пожирателя конфет, ест любые конфеты, но так как захочет.
*/
public interface ICandyEater {
/**
* Съесть конфету, может занять время
*
* @param candy
*/
void eat(ICandy candy) throws Exception;
}
/**
* Сервис пожирания конфет, требует реализации
*/
public abstract class CandyServiceBase {
/**
* Сервис получает при инициализации массив доступных пожирателей конфет
*
* @param candyEaters
*/
public CandyServiceBase(ICandyEater[] candyEaters) {
}
/**
* Добавить конфету на съедение
*
* @param candy
*/
public abstract void addCandy(ICandy candy);
}
public class CandyService extends CandyServiceBase {
private final BlockingQueue<ICandy> candies = new LinkedBlockingQueue<>();
private final CopyOnWriteArraySet<Integer> eatNow = new CopyOnWriteArraySet();
public CandyService(ICandyEater[] candyEaters) {
super(candyEaters);
for (ICandyEater candyEater : candyEaters) {
new Thread(() -> {
while (true) {
final CopyOnWriteArraySet<Integer> eatNow = this.eatNow;
candies.stream().distinct().filter(iCandies -> !eatNow.contains(iCandies.getCandyFlavour()))
.findFirst().ifPresent(iCandies -> {
eatNow.add(iCandies.getCandyFlavour());
try {
candyEater.eat(iCandies);
} catch (Exception e) {
e.printStackTrace();
}
eatNow.remove(iCandies.getCandyFlavour());
});
}
}).start();
}
}
@Override
public void addCandy(ICandy candy) {
candies.offer(candy);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment