diff --git a/ermolmak/pom.xml b/ermolmak/pom.xml
new file mode 100644
index 00000000..6245c2df
--- /dev/null
+++ b/ermolmak/pom.xml
@@ -0,0 +1,41 @@
+
+
+ 4.0.0
+
+ ru.fizteh.fivt.students
+ parent
+ 1.0-SNAPSHOT
+
+ ru.fizteh.fivt.students
+ ermolmak
+ 1.0-SNAPSHOT
+ ermolmak
+ http://maven.apache.org
+
+ UTF-8
+
+
+
+ junit
+ junit
+ [3.8.1,)
+ test
+
+
+ com.beust
+ jcommander
+ 1.48
+
+
+ org.twitter4j
+ twitter4j-core
+ 4.0.4
+
+
+ org.twitter4j
+ twitter4j-stream
+ [4.0,)
+
+
+
diff --git a/ermolmak/src/main/java/ru/fizteh/fivt/students/ermolmak/threads/blockingqueue/BlockingQueue.java b/ermolmak/src/main/java/ru/fizteh/fivt/students/ermolmak/threads/blockingqueue/BlockingQueue.java
new file mode 100644
index 00000000..caf75ff8
--- /dev/null
+++ b/ermolmak/src/main/java/ru/fizteh/fivt/students/ermolmak/threads/blockingqueue/BlockingQueue.java
@@ -0,0 +1,36 @@
+package ru.fizteh.fivt.students.ermolmak.threads.blockingqueue;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+
+public class BlockingQueue {
+ private final int maxSize;
+ private Queue queue;
+
+ public BlockingQueue(int maxSize) {
+ this.maxSize = maxSize;
+ queue = new LinkedList<>();
+ }
+
+ public synchronized void offer(List e) throws InterruptedException {
+ while (queue.size() + e.size() > maxSize) {
+ wait();
+ }
+ queue.addAll(e);
+ notifyAll();
+ }
+
+ public synchronized List take(int n) throws InterruptedException {
+ while (queue.size() < n) {
+ wait();
+ }
+ List result = new ArrayList<>();
+ for (int i = 0; i < n; ++i) {
+ result.add(queue.remove());
+ }
+ notifyAll();
+ return result;
+ }
+}
diff --git a/ermolmak/src/main/java/ru/fizteh/fivt/students/ermolmak/threads/call/Call.java b/ermolmak/src/main/java/ru/fizteh/fivt/students/ermolmak/threads/call/Call.java
new file mode 100644
index 00000000..a3b2b3b4
--- /dev/null
+++ b/ermolmak/src/main/java/ru/fizteh/fivt/students/ermolmak/threads/call/Call.java
@@ -0,0 +1,24 @@
+package ru.fizteh.fivt.students.ermolmak.threads.call;
+
+public class Call {
+ public static void main(String[] args) {
+ if (args.length == 1) {
+ try {
+ int num = Integer.parseInt(args[0]);
+ if (num > 0) {
+ (new Thread(new Caller(num))).start();
+ } else {
+ printUsage();
+ }
+ } catch (NumberFormatException e) {
+ printUsage();
+ }
+ } else {
+ printUsage();
+ }
+ }
+
+ private static void printUsage() {
+ System.out.println("Usase: Call {number of threads}");
+ }
+}
diff --git a/ermolmak/src/main/java/ru/fizteh/fivt/students/ermolmak/threads/call/Caller.java b/ermolmak/src/main/java/ru/fizteh/fivt/students/ermolmak/threads/call/Caller.java
new file mode 100644
index 00000000..a57991e7
--- /dev/null
+++ b/ermolmak/src/main/java/ru/fizteh/fivt/students/ermolmak/threads/call/Caller.java
@@ -0,0 +1,108 @@
+package ru.fizteh.fivt.students.ermolmak.threads.call;
+
+class Caller implements Runnable {
+ private final int numberOfThreads;
+ private final boolean[] answers;
+ private final Object monitor;
+ private Turn turn;
+ private int unansweredThreads;
+ private int yesCounter;
+
+ Caller(int numberOfThreads) {
+ this.numberOfThreads = numberOfThreads;
+ answers = new boolean[numberOfThreads];
+ monitor = new Object();
+ }
+
+ private void reset() {
+ unansweredThreads = numberOfThreads;
+ yesCounter = 0;
+ for (int i = 0; i < numberOfThreads; ++i) {
+ answers[i] = false;
+ }
+ }
+
+ @Override
+ public void run() {
+ turn = Turn.MAIN_THREAD;
+ for (int i = 0; i < numberOfThreads; ++i) {
+ (new Thread(new ChildThread(i))).start();
+ }
+ reset();
+
+ while (yesCounter != numberOfThreads) {
+ synchronized (monitor) {
+ System.out.println("Are you ready?");
+ turn = Turn.CHILD_THREAD;
+ monitor.notifyAll();
+ while (turn == Turn.CHILD_THREAD) {
+ try {
+ monitor.wait();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ if (yesCounter != numberOfThreads) {
+ reset();
+ }
+ }
+ }
+ }
+
+ private enum Turn {
+ MAIN_THREAD,
+ CHILD_THREAD
+ }
+
+ private class ChildThread implements Runnable {
+ private final int myNumber;
+
+ ChildThread(int myNumber) {
+ this.myNumber = myNumber;
+ }
+
+ private boolean getAnswer() {
+ return Math.random() < 0.9;
+ }
+
+ @Override
+ public void run() {
+ while (yesCounter != numberOfThreads) {
+ synchronized (monitor) {
+ while (turn == Turn.MAIN_THREAD) {
+ try {
+ monitor.wait();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ boolean answer = getAnswer();
+ if (answer) {
+ ++yesCounter;
+ System.out.println("Yes");
+ } else {
+ System.out.println("No");
+ }
+ --unansweredThreads;
+ answers[myNumber] = true;
+
+ if (unansweredThreads == 0) {
+ turn = Turn.MAIN_THREAD;
+ monitor.notifyAll();
+ continue;
+ }
+
+ while (answers[myNumber] & yesCounter != numberOfThreads) {
+ try {
+ monitor.wait();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/ermolmak/src/main/java/ru/fizteh/fivt/students/ermolmak/threads/counter/Counter.java b/ermolmak/src/main/java/ru/fizteh/fivt/students/ermolmak/threads/counter/Counter.java
new file mode 100644
index 00000000..7ff76ca4
--- /dev/null
+++ b/ermolmak/src/main/java/ru/fizteh/fivt/students/ermolmak/threads/counter/Counter.java
@@ -0,0 +1,25 @@
+package ru.fizteh.fivt.students.ermolmak.threads.counter;
+
+
+public class Counter {
+ public static void main(String[] args) {
+ if (args.length == 0) {
+ printUsage();
+ } else {
+ try {
+ int numberOfThreads = Integer.parseInt(args[0]);
+ if (numberOfThreads > 0) {
+ new CounterLauncher(numberOfThreads);
+ } else {
+ printUsage();
+ }
+ } catch (NumberFormatException e) {
+ printUsage();
+ }
+ }
+ }
+
+ static void printUsage() {
+ System.out.println("Usage: Counter {number of threads}");
+ }
+}
diff --git a/ermolmak/src/main/java/ru/fizteh/fivt/students/ermolmak/threads/counter/CounterLauncher.java b/ermolmak/src/main/java/ru/fizteh/fivt/students/ermolmak/threads/counter/CounterLauncher.java
new file mode 100644
index 00000000..17f17b25
--- /dev/null
+++ b/ermolmak/src/main/java/ru/fizteh/fivt/students/ermolmak/threads/counter/CounterLauncher.java
@@ -0,0 +1,50 @@
+package ru.fizteh.fivt.students.ermolmak.threads.counter;
+
+class CounterLauncher {
+ private int numberOfThreads;
+ private Integer currentThread;
+ private Object monitor;
+
+ CounterLauncher(int numberOfThreads) {
+ this.numberOfThreads = numberOfThreads;
+ this.currentThread = 0;
+ monitor = new Object();
+
+ for (int i = 0; i < numberOfThreads; ++i) {
+ (new Thread(new CounterThread(i))).start();
+ }
+ }
+
+ class CounterThread implements Runnable {
+ private int myNum;
+
+ CounterThread(int number) {
+ myNum = number;
+ }
+
+ @Override
+ public void run() {
+ while (true) {
+ synchronized (monitor) {
+ while (currentThread != myNum) {
+ try {
+ monitor.wait();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ ++currentThread;
+ System.out.println("Thread-" + currentThread);
+ currentThread %= numberOfThreads;
+ monitor.notifyAll();
+
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/ermolmak/src/main/java/ru/fizteh/fivt/students/ermolmak/twitterstream/Area.java b/ermolmak/src/main/java/ru/fizteh/fivt/students/ermolmak/twitterstream/Area.java
new file mode 100644
index 00000000..b9ac8d4c
--- /dev/null
+++ b/ermolmak/src/main/java/ru/fizteh/fivt/students/ermolmak/twitterstream/Area.java
@@ -0,0 +1,29 @@
+package ru.fizteh.fivt.students.ermolmak.twitterstream;
+
+import twitter4j.GeoLocation;
+
+class Area {
+ private GeoLocation location;
+ private double radius;
+
+ Area(GeoLocation location, double radius) {
+ this.location = location;
+ this.radius = radius;
+ }
+
+ public GeoLocation getLocation() {
+ return location;
+ }
+
+ public void setLocation(GeoLocation location) {
+ this.location = location;
+ }
+
+ public double getRadius() {
+ return radius;
+ }
+
+ public void setRadius(double radius) {
+ this.radius = radius;
+ }
+}
diff --git a/ermolmak/src/main/java/ru/fizteh/fivt/students/ermolmak/twitterstream/GeoResolver.java b/ermolmak/src/main/java/ru/fizteh/fivt/students/ermolmak/twitterstream/GeoResolver.java
new file mode 100644
index 00000000..664b55d8
--- /dev/null
+++ b/ermolmak/src/main/java/ru/fizteh/fivt/students/ermolmak/twitterstream/GeoResolver.java
@@ -0,0 +1,90 @@
+package ru.fizteh.fivt.students.ermolmak.twitterstream;
+
+import twitter4j.GeoLocation;
+import twitter4j.JSONException;
+import twitter4j.JSONObject;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Properties;
+
+class GeoResolver {
+ private String googleKey;
+
+ GeoResolver() throws IOException {
+ Properties properties = new Properties();
+ InputStream inputStream = this.getClass().getResourceAsStream("/GoogleMapsKey.properties");
+ properties.load(inputStream);
+ googleKey = properties.getProperty("key");
+ }
+
+ private String googleMaps(String place) throws IOException {
+ URL url = new URL("https://maps.googleapis.com/maps/api/geocode/json?address="
+ + place + "&key=" + googleKey);
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.connect();
+
+// if (connection.getResponseCode() >= 400) {
+// // TODO
+// }
+
+ InputStream googleAnswer = connection.getInputStream();
+ String strGoogleAnswer;
+
+ try (BufferedReader in = new BufferedReader(new InputStreamReader(googleAnswer))) {
+ String current;
+ StringBuilder answer = new StringBuilder();
+ while ((current = in.readLine()) != null) {
+ answer.append(current);
+ }
+ strGoogleAnswer = answer.toString();
+ }
+
+ googleAnswer.close();
+ connection.disconnect();
+ return strGoogleAnswer;
+ }
+
+ private GeoLocation locationFromJSON(JSONObject location) throws JSONException {
+ return new GeoLocation(
+ Double.parseDouble(location.getString("lat")),
+ Double.parseDouble(location.getString("lng")));
+ }
+
+ static double distance(GeoLocation loc1, GeoLocation loc2) {
+ final double radius = 6370;
+ double cosAng = Math.cos(loc1.getLatitude() * Math.PI / 180)
+ * Math.cos(loc2.getLatitude() * Math.PI / 180)
+ * Math.cos((loc1.getLongitude() - loc2.getLongitude()) * Math.PI / 180)
+
+ + Math.sin(loc1.getLongitude() * Math.PI / 180)
+ * Math.sin(loc2.getLongitude() * Math.PI / 180);
+
+ return radius * Math.acos(cosAng);
+ }
+
+ Area findPlace(String place) throws IOException, JSONException {
+ JSONObject json = new JSONObject(googleMaps(place));
+
+// if (!json.getString("status").equals("OK")) {
+// // TODO
+// }
+
+ JSONObject geometry = json
+ .getJSONArray("results")
+ .getJSONObject(0)
+ .getJSONObject("geometry");
+
+ JSONObject northeast = geometry.getJSONObject("bounds").getJSONObject("northeast");
+ JSONObject southwest = geometry.getJSONObject("bounds").getJSONObject("southwest");
+ JSONObject location = geometry.getJSONObject("location");
+
+ double radius = distance(locationFromJSON(northeast), locationFromJSON(southwest)) / 2;
+
+ return new Area(locationFromJSON(location), radius);
+ }
+}
diff --git a/ermolmak/src/main/java/ru/fizteh/fivt/students/ermolmak/twitterstream/Parser.java b/ermolmak/src/main/java/ru/fizteh/fivt/students/ermolmak/twitterstream/Parser.java
new file mode 100644
index 00000000..72856f12
--- /dev/null
+++ b/ermolmak/src/main/java/ru/fizteh/fivt/students/ermolmak/twitterstream/Parser.java
@@ -0,0 +1,47 @@
+package ru.fizteh.fivt.students.ermolmak.twitterstream;
+
+import com.beust.jcommander.Parameter;
+
+public class Parser {
+ @Parameter(names = {"--query", "-q"}, description = "Keywords")
+ private String query = null;
+
+ @Parameter(names = {"--place", "-p"}, description = "Places for search")
+ private String place = null;
+
+ @Parameter(names = {"--stream", "-s"}, description = "Stream mode")
+ private boolean stream = false;
+
+ @Parameter(names = "--hideRetweets", description = "Hide Retweets")
+ private boolean hideRetweets = false;
+
+ @Parameter(names = {"--limit", "-l"}, description = "Limit of tweets")
+ private int limit = 10;
+
+ @Parameter(names = {"--help", "-h"}, description = "Prints this help")
+ private boolean help = false;
+
+ public String getQuery() {
+ return query;
+ }
+
+ public String getPlace() {
+ return place;
+ }
+
+ public boolean isStream() {
+ return stream;
+ }
+
+ public boolean isHideRetweets() {
+ return hideRetweets;
+ }
+
+ public int getLimit() {
+ return limit;
+ }
+
+ public boolean isHelp() {
+ return help;
+ }
+}
diff --git a/ermolmak/src/main/java/ru/fizteh/fivt/students/ermolmak/twitterstream/SearchTweets.java b/ermolmak/src/main/java/ru/fizteh/fivt/students/ermolmak/twitterstream/SearchTweets.java
new file mode 100644
index 00000000..ce11e3d6
--- /dev/null
+++ b/ermolmak/src/main/java/ru/fizteh/fivt/students/ermolmak/twitterstream/SearchTweets.java
@@ -0,0 +1,142 @@
+package ru.fizteh.fivt.students.ermolmak.twitterstream;
+
+import twitter4j.*;
+
+import java.util.*;
+
+public class SearchTweets {
+ private static final long MILLIS_IN_SECOND = 1000L;
+ private static final long MILLIS_IN_MINUTE = 60_000L;
+ private static final long MILLIS_IN_HOUR = 3_600_000L;
+ private static final long MILLIS_IN_DAY = MILLIS_IN_HOUR * 24;
+
+ String tweetRepresentation(Status status, boolean hideRetweets) {
+ if (status.isRetweet()) {
+ if (hideRetweets) {
+ return null;
+ }
+
+ return getTweetTime(status.getCreatedAt())
+ + " @" + status.getUser().getName()
+ + ": ретвитнул @" + status.getRetweetedStatus().getUser().getName()
+ + ": " + status.getText();
+ } else {
+ if (status.getRetweetCount() > 0) {
+ return getTweetTime(status.getCreatedAt())
+ + " @" + status.getUser().getName()
+ + ": " + status.getText()
+ + (" (" + status.getRetweetCount() + " ретвитов)");
+ } else {
+ return getTweetTime(status.getCreatedAt())
+ + " @" + status.getUser().getName()
+ + ": " + status.getText();
+ }
+ }
+ }
+
+ private String getTweetTime(Date date) {
+ Calendar now = new GregorianCalendar();
+ Calendar tweetTime = new GregorianCalendar.Builder().setInstant(date).build();
+
+ long milliseconds = now.getTimeInMillis() - tweetTime.getTimeInMillis();
+
+ boolean isToday = now.get(Calendar.DATE) == tweetTime.get(Calendar.DATE)
+ && milliseconds < MILLIS_IN_DAY;
+
+ String result;
+ if (isToday) {
+ if (milliseconds < 2 * MILLIS_IN_MINUTE) {
+ result = "Только что";
+ } else if (milliseconds < MILLIS_IN_HOUR) {
+ result = milliseconds / MILLIS_IN_MINUTE + " минут назад";
+ } else {
+ result = milliseconds / MILLIS_IN_HOUR + " часов назад";
+ }
+ } else {
+ tweetTime.set(Calendar.HOUR_OF_DAY, 0);
+ tweetTime.set(Calendar.MINUTE, 0);
+ tweetTime.set(Calendar.SECOND, 0);
+ tweetTime.set(Calendar.MILLISECOND, 0);
+
+ now.set(Calendar.HOUR_OF_DAY, 0);
+ now.set(Calendar.MINUTE, 0);
+ now.set(Calendar.SECOND, 0);
+ now.set(Calendar.MILLISECOND, 0);
+
+ long days = (now.getTimeInMillis() - tweetTime.getTimeInMillis()) / MILLIS_IN_DAY;
+
+ if (days == 1) {
+ result = "Вчера";
+ } else {
+ result = days + " дней назад";
+ }
+ }
+
+ return result;
+ }
+
+ List searchTweets(String stringQuery,
+ Area place,
+ boolean hideRetweets,
+ int limit) throws TwitterException {
+ Twitter twitter = new TwitterFactory().getInstance();
+ Query query = new Query(stringQuery);
+ if (place != null) {
+ query = query.geoCode(place.getLocation(), place.getRadius(), "km");
+ }
+
+ List tweets = new ArrayList<>();
+ while (tweets.size() < limit && query != null) {
+ QueryResult queryResult = twitter.search(query);
+ for (Status status : queryResult.getTweets()) {
+ if (tweets.size() == limit) {
+ break;
+ }
+
+ String tweetString = tweetRepresentation(status, hideRetweets);
+ if (tweetString != null) {
+ tweets.add(tweetString);
+ }
+ }
+ query = queryResult.nextQuery();
+ }
+
+ return tweets;
+ }
+
+// public void stream(String stringQuery,
+// Area area,
+// boolean hideRetweets,
+// Consumer tweetFunction,
+// twitter4j.TwitterStream twitterStream) {
+// twitterStream.addListener(new StatusAdapter() {
+// @Override
+// public void onStatus(Status status) {
+// if (hideRetweets && status.isRetweet()) {
+// return;
+// }
+//
+// GeoLocation tweetLocation;
+// GeoResolver geoResolver = null;
+// try {
+// geoResolver = new GeoResolver();
+// } catch (IOException e) {
+// e.printStackTrace();
+// }
+// if (status.getGeoLocation() != null) {
+// tweetLocation = status.getGeoLocation();
+// } else {
+// return;
+// }
+//
+// if (GeoResolver.distance(area.getLocation(), tweetLocation) < area.getRadius()) {
+// tweetFunction.accept(tweetRepresentation(status, hideRetweets));
+// }
+// }
+// });
+//
+// String[] strings = new String[1];
+// strings[0] = stringQuery;
+// twitterStream.filter(new FilterQuery().track(strings));
+// }
+}
diff --git a/ermolmak/src/main/java/ru/fizteh/fivt/students/ermolmak/twitterstream/TwitterStream.java b/ermolmak/src/main/java/ru/fizteh/fivt/students/ermolmak/twitterstream/TwitterStream.java
new file mode 100644
index 00000000..198427b1
--- /dev/null
+++ b/ermolmak/src/main/java/ru/fizteh/fivt/students/ermolmak/twitterstream/TwitterStream.java
@@ -0,0 +1,50 @@
+package ru.fizteh.fivt.students.ermolmak.twitterstream;
+
+import com.beust.jcommander.JCommander;
+import twitter4j.JSONException;
+import twitter4j.TwitterException;
+
+import java.io.IOException;
+import java.util.List;
+
+public class TwitterStream {
+ public static void main(String[] args) throws TwitterException, IOException, JSONException {
+ Parser parser = new Parser();
+ JCommander jCommander = new JCommander(parser, args);
+ String stringQuery = parser.getQuery();
+
+ if (parser.isHelp()) {
+ jCommander.usage();
+ return;
+ }
+
+ String place = parser.getPlace();
+ Area area = null;
+ if (place != null) {
+ GeoResolver geoResolver = new GeoResolver();
+ area = geoResolver.findPlace(place);
+ }
+
+ SearchTweets search = new SearchTweets();
+ if (!parser.isStream()) {
+
+ List tweets = search.searchTweets(
+ stringQuery,
+ area,
+ parser.isHideRetweets(),
+ parser.getLimit());
+
+ for (String tweet : tweets) {
+ System.out.println(tweet);
+ System.out.println();
+ }
+// } else {
+// search.stream(
+// stringQuery,
+// area,
+// parser.isHideRetweets(),
+// System.out::print,
+// (new TwitterStreamFactory()).getInstance());
+ }
+ }
+}
diff --git a/ermolmak/src/test/java/ru/fizteh/fivt/students/ermolmak/threads/blockingqueue/Tests.java b/ermolmak/src/test/java/ru/fizteh/fivt/students/ermolmak/threads/blockingqueue/Tests.java
new file mode 100644
index 00000000..7f43c3d4
--- /dev/null
+++ b/ermolmak/src/test/java/ru/fizteh/fivt/students/ermolmak/threads/blockingqueue/Tests.java
@@ -0,0 +1,178 @@
+package ru.fizteh.fivt.students.ermolmak.threads.blockingqueue;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class Tests {
+ private List arrayToList(Integer[] a) {
+ List result = new ArrayList<>();
+ Collections.addAll(result, a);
+ return result;
+ }
+
+ @Test
+ public void test1() {
+ Integer[] a = { 1, 2, 3, 4 };
+ List listA = arrayToList(a);
+ BlockingQueue blockingQueue = new BlockingQueue<>(5);
+
+ try {
+ blockingQueue.offer(arrayToList(a));
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ List listB = new ArrayList<>();
+ try {
+ listB = blockingQueue.take(2);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ Assert.fail();
+ }
+
+ Assert.assertArrayEquals(listA.subList(0, 2).toArray(a), listB.toArray(a));
+
+ try {
+ listB = blockingQueue.take(2);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ Assert.fail();
+ }
+
+ Assert.assertArrayEquals(listA.subList(2, 4).toArray(a), listB.toArray(a));
+ }
+
+ @Test
+ public void test2() {
+ Integer[] a = { 1, 2, 3, 4, 5, 6, 7 };
+ List listA = arrayToList(a);
+ BlockingQueue blockingQueue = new BlockingQueue<>(7);
+
+ try {
+ blockingQueue.offer(arrayToList(a));
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ List listB = new ArrayList<>();
+ try {
+ listB = blockingQueue.take(7);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ Assert.fail();
+ }
+
+ Assert.assertArrayEquals(listA.toArray(a), listB.toArray(a));
+ }
+
+ @Test
+ public void blockingTest1() {
+ Integer[] a = { 1, 2, 3 };
+ Integer[] b = { 4, 5, 6 };
+ Integer[] c = { 7, 8, 9 };
+ Integer[] r = { 1, 2, 3, 4, 5, 6, 7 };
+
+ BlockingQueue blockingQueue = new BlockingQueue<>(15);
+
+ try {
+ Thread threadA = new Thread(new OfferThread(blockingQueue, arrayToList(a)));
+ threadA.start();
+ threadA.join();
+
+ Thread threadB = new Thread(new OfferThread(blockingQueue, arrayToList(b)));
+ threadB.start();
+ threadB.join();
+
+ Thread threadR = new Thread(new TakeThread(blockingQueue, 7, arrayToList(r)));
+ threadR.start();
+
+ Thread threadC = new Thread(new OfferThread(blockingQueue, arrayToList(c)));
+ threadC.start();
+ threadC.join();
+
+ threadR.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Test
+ public void blockingTest2() {
+ BlockingQueue blockingQueue = new BlockingQueue<>(6);
+
+ Integer[] a = { 1, 2, 3 };
+ Integer[] b = { 4, 5, 6, 7 };
+ Integer[] r1 = { 1, 2 };
+ Integer[] r2 = { 3, 4, 5, 6, 7 };
+
+ try {
+ Thread threadA = new Thread(new OfferThread(blockingQueue, arrayToList(a)));
+ threadA.start();
+ threadA.join();
+
+ Thread threadB = new Thread(new OfferThread(blockingQueue, arrayToList(b)));
+ threadB.start();
+// threadB.join();
+
+ Thread threadR1 = new Thread(new TakeThread(blockingQueue, 2, arrayToList(r1)));
+ threadR1.start();
+ threadR1.join();
+
+ Thread threadR2 = new Thread(new TakeThread(blockingQueue, 5, arrayToList(r2)));
+ threadR2.start();
+ threadR2.join();
+
+ threadB.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ Assert.fail();
+ }
+ }
+
+ private class OfferThread implements Runnable {
+ private final BlockingQueue blockingQueue;
+ private final List offered;
+
+ private OfferThread(BlockingQueue blockingQueue, List offered) {
+ this.blockingQueue = blockingQueue;
+ this.offered = offered;
+ }
+
+ @Override
+ public void run() {
+ try {
+ blockingQueue.offer(offered);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ Assert.fail();
+ }
+ }
+ }
+
+ private class TakeThread implements Runnable {
+ private final BlockingQueue blockingQueue;
+ private final int num;
+ private final List expected;
+
+ private TakeThread(BlockingQueue blockingQueue, int num, List expected) {
+ this.blockingQueue = blockingQueue;
+ this.num = num;
+ this.expected = expected;
+ }
+
+ @Override
+ public void run() {
+ try {
+ List result = blockingQueue.take(num);
+ Assert.assertArrayEquals(expected.toArray(new Integer[0]), result.toArray(new Integer[0]));
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ Assert.fail();
+ }
+ }
+ }
+}
diff --git a/pom.xml b/pom.xml
index a2fdfbd2..f73781cf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -42,10 +42,11 @@
Jettriangle
nmakeenkov
- oshch
+ oshch
ladyae
- nikitarykov
- duha666
+ ermolmak
+ nikitarykov
+ duha666