Created
June 3, 2019 08:09
-
-
Save findli/dcdc59a9fa9701a5ab67b3acee79d676 to your computer and use it in GitHub Desktop.
CandyServiceBase test case
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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