From 9611a96de864783106ae330c7ac8277cdbd73866 Mon Sep 17 00:00:00 2001 From: "life@u-rise.com" Date: Mon, 4 Jul 2016 13:09:25 +0300 Subject: [PATCH 01/11] Add Matrix entrance task --- .gitignore | 8 ++ README.md | 84 ++++++++++++++----- pom.xml | 44 ++++++++++ src/main/java/ru/javaops/masterjava/Main.java | 14 ++++ .../javaops/masterjava/matrix/MainMatrix.java | 23 +++++ .../javaops/masterjava/matrix/MatrixUtil.java | 24 ++++++ 6 files changed, 176 insertions(+), 21 deletions(-) create mode 100644 .gitignore create mode 100644 pom.xml create mode 100644 src/main/java/ru/javaops/masterjava/Main.java create mode 100644 src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java create mode 100644 src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..6ca05c4a5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +.idea +out +target +*.iml +log + + + diff --git a/README.md b/README.md index ed139bed8..17463736d 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,65 @@ -#### Написание с нуля полнофункционального многомодульного Maven проекта: -веб приложения (Tomcat, JSP, jQuery), -многопоточного почтового сервиса (JavaMail, java.util.concurrent.*) и вспомогательных модулей связанных по Веб и REST сервисам (SOAP, JAX-WS, Axis, JAX-RS) -c сохранением данных в RMDBS и динамическим конфигурирование модулей по JMX. +# Многопоточность. Веб сервисы. +### _Разработка полнофункционального многомодульного Maven проекта_ +- веб приложение (Tomcat, JSP, jQuery), +- многопоточный почтовый сервиса (JavaMail, java.util.concurrent.*) +- вспомогательные модули, связанные по веб-сервисам (SOAP, JAX-WS) и по REST (JAX-RS) +- сохранение данных в RMDBS (H2) и динамическое конфигурирование модулей по JMX. -## Сервис-ориентированная архитектура, Микросервисы +## Необходимое на курсе ПО +- JDK8 +- Git +- IntelliJ IDEA + +> Выбирать Ultimate, 30 days trial (работа с JavaScript, Tomcat, JSP). Учебный ключ к Ultimate выдается на первом занятии. + +## Многопоточность +![Concurrent vs Parallel](https://joearms.github.io/images/con_and_par.jpg) +- Java Memory Model +- Синхронизация потоков +- Обзор java.util.concurrent.* +- Использование ThreadLocal переменных + +#### Основы, доп. материалы +- Intuit, Потоки выполнения. Синхронизация +- Алексей Владыкин, Основы многопоточность в Java +- Виталий Чибриков, Java. Многопоточность +- Computer Science Center, курс Параллельное программирование +- Юрий Ткач, курс Advanced Java - Concurrency +- Головач, курс Java Multithreading + +--- +# Вступительное задание: +Вычекать этот проект: +```git clone https://github.com/JavaOPs/masterjava.git``` + +Реализовать класс `MainMatrix`, позволяющий многопоточно перемножать квадратные матрицы N*N. +- Количество дочерних потоков ограничено M (Mоптимизации +- Сделать несколько вариантов решения: + - Объязательно: используя только механизмы синхронизации Java 1.4 + - Опционально: без ограничений + +----- +# Программа курса +> **возможны изменения, окончательная программа будет перед стартом курса** + +### Concurrent and Parallel Programming +- Thread safety. Java Memory Model/ JSR 133. Happens-before. +- Публикация объектов. Использование ThreadLocal переменных +- Initialization on demand holder / Double-checked locking +- Обзор java.util.concurrent.* + +### Сервис-ориентированная архитектура, Микросервисы - JMS, альтернативы - Варианты разворачивания сервисов. Работа с базой. Связывание сервисов. -## Maven. Многомодульный Maven проект +### Maven. Многомодульный Maven проект - Build Lifecycle - Dependency Mechanism - Зависимости, профили, написание плагина - The Reactor. Snapshots -## Создание/тестирование веб-приложения. +### Создание/тестирование веб-приложения. - Сборка, запуск, локальный и удаленный debug проекта, способы деплоя в Tomcat - tomcat7-maven-plugin @@ -23,20 +69,20 @@ c сохранением данных в RMDBS и динамическим ко - Создание API и реализации веб-сервиса MailService. - Деплой и тестирование через SoapUI. -## Доработка веб-сервиса. Кастомизация WSDL. +### Доработка веб-сервиса. Кастомизация WSDL. - Работа с JAXB. - Передача по SOAP Exception - Включение wsdl в сервис для публикации. - Генерация java кода по WSDL -## Реализация клиент веб-сервиса. +### Реализация клиент веб-сервиса. - Публикация веб сервиса из main(). Дабавление wsdl - Выделение из wsdl общей части - Создание клиента почтового сервиса. - Тестирование с помощью JUnit 4 - Интеграционное тестирование, maven-failsafe-plugin -## JAX-WS Handlers +### JAX-WS Handlers - Logical/protocol handlers. - Логирование SOAP на стороне клиента. - Логирование и статистика трафика опубликованного веб-сервиса. @@ -44,38 +90,34 @@ c сохранением данных в RMDBS и динамическим ко - SoapHandler аутентификация. Добавляем файлы вложения. Mail-Service. -## Создаем вложения почты +### Создаем вложения почты - Генерация обновленного WSDL через wsgen - Веб-сервисы: JAX-WS attachment with MTOM - Тестирование вложений через SoapUi. -## Загрузка файлов. +### Загрузка файлов. - Стандарт MIME. Обрабатываем вложения на форме: commons-fileupload - Загрузка файла вместе в полями формы. - Вызов клиента с вложениями. -## Персистентность. +### Персистентность. - NoSQL or RDBMS. Обзор NoSQL систем. CAP - Обзор Java persistence solution: commons-dbutils, Spring JdbcTemplate, MyBatis, JOOQ, ORM (Hibernate, TopLink, ElipseLink, EBean used in Playframework). JPA. JPA Performance Benchmark - Работа с базой: создание базы, настройка IDEA Database. - Работа с DB через DataSource, настройка tomcat. HikariCP - Настройка работы с DataSource из JUnit. -## REST веб сервис. +### REST веб сервис. - JAX-RS. Интеграция с Jersey - Поддержка Json. Jackson -## Асинхронность. +### Асинхронность. - @OneWay vs Java Execution framework - Добавление в клиенте асинхронных вызовов. - Асинхронные сервлеты 3.x в Tomcat -## Динамическое конфигурирование. JMX +### Динамическое конфигурирование. JMX - Maven Groovy cкрптинг. groovy-maven-plugin - Настройка Tomcat на удаленное администрирование по JMX -## Отправка email в многопоточном приложении -- Initialization on demand holder / Double-checked locking -- java.util.concurrent.*: Executors , Synchronizers, Concurrent Collections, Lock - -## Проблема MemoryLeak. Поиск утечки памяти. +### Проблема MemoryLeak. Поиск утечки памяти. diff --git a/pom.xml b/pom.xml new file mode 100644 index 000000000..39e811e08 --- /dev/null +++ b/pom.xml @@ -0,0 +1,44 @@ + + 4.0.0 + + ru.javaops + masterjava + jar + + 1.0-SNAPSHOT + + Master Java + https://github.com/JavaOPs/masterjava + + + 1.8 + UTF-8 + UTF-8 + + + + masterjava + install + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + ${java.version} + ${java.version} + + + + + + + + + + + + + + diff --git a/src/main/java/ru/javaops/masterjava/Main.java b/src/main/java/ru/javaops/masterjava/Main.java new file mode 100644 index 000000000..a849258c4 --- /dev/null +++ b/src/main/java/ru/javaops/masterjava/Main.java @@ -0,0 +1,14 @@ +package ru.javaops.masterjava; + +/** + * User: gkislin + * Date: 05.08.2015 + * + * @link http://caloriesmng.herokuapp.com/ + * @link https://github.com/JavaOPs/topjava + */ +public class Main { + public static void main(String[] args) { + System.out.format("Hello MasterJava!"); + } +} diff --git a/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java b/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java new file mode 100644 index 000000000..28f28dc9f --- /dev/null +++ b/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java @@ -0,0 +1,23 @@ +package ru.javaops.masterjava.matrix; + +/** + * gkislin + * 03.07.2016 + */ +public class MainMatrix { + // Multiplex matrix + private static final int MATRIX_SIZE = 1000; + private static final int THREAD_NUMBER = 10; + + public static void main(String[] args) { + final int[][] matrixA = new int[MATRIX_SIZE][MATRIX_SIZE]; + final int[][] matrixB = new int[MATRIX_SIZE][MATRIX_SIZE]; + + long start = System.currentTimeMillis(); + final int[][] matrixC = MatrixUtil.singleThreadMultiply(matrixA, matrixB); + System.out.println("Single thread multiplication time, sec: " + (System.currentTimeMillis() - start)/1000.); + + // TODO implement parallel multiplication matrixA*matrixB + // TODO compare wih matrixC; + } +} diff --git a/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java b/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java new file mode 100644 index 000000000..9e01a338b --- /dev/null +++ b/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java @@ -0,0 +1,24 @@ +package ru.javaops.masterjava.matrix; + +/** + * gkislin + * 03.07.2016 + */ +public class MatrixUtil { + + public static int[][] singleThreadMultiply(int[][] matrixA, int[][] matrixB) { + final int matrixSize = matrixA.length; + final int[][] matrixC = new int[matrixSize][matrixSize]; + + for (int i = 0; i < matrixSize; i++) { + for (int j = 0; j < matrixSize; j++) { + int sum = 0; + for (int k = 0; k < matrixSize; k++) { + sum += matrixA[i][k] * matrixB[k][j]; + } + matrixC[i][j] = sum; + } + } + return matrixC; + } +} From ebabca1a6c3ecca20bf8973d7e1f21f12e54fbbb Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Wed, 13 Jul 2016 14:24:42 +0300 Subject: [PATCH 02/11] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 17463736d..47bca0cc2 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,9 @@ - вспомогательные модули, связанные по веб-сервисам (SOAP, JAX-WS) и по REST (JAX-RS) - сохранение данных в RMDBS (H2) и динамическое конфигурирование модулей по JMX. +### Требование к участникам +Опыт программирования на Java. Базовые знания Maven. + ## Необходимое на курсе ПО - JDK8 - Git From c6fe5b4ab87d2d5f611a1d16f3b5234df6c9fc6f Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Wed, 13 Jul 2016 14:35:38 +0300 Subject: [PATCH 03/11] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 47bca0cc2..a5b2a6338 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # Многопоточность. Веб сервисы. ### _Разработка полнофункционального многомодульного Maven проекта_ -- веб приложение (Tomcat, JSP, jQuery), -- многопоточный почтовый сервиса (JavaMail, java.util.concurrent.*) -- вспомогательные модули, связанные по веб-сервисам (SOAP, JAX-WS) и по REST (JAX-RS) +- веб приложение (Tomcat, JSP, jQuery) +- многопоточный почтовый сервиса (JavaMail, java.util.concurrent.*) и вспомогательные модули +- связь модулей через веб-сервисы (SOAP, JAX-WS) и по REST (JAX-RS) - сохранение данных в RMDBS (H2) и динамическое конфигурирование модулей по JMX. ### Требование к участникам From 204f744eef3ea3535685678fcda10108abc67a9b Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Fri, 15 Jul 2016 18:56:16 +0300 Subject: [PATCH 04/11] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a5b2a6338..5100019e6 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ ### Веб-сервисы - Веб-сервисы. SOAP. Преимущества/недостатки веб-сервисов. Расширения. -- Реализация веб-сервисов в Java. JAX-RPC, JAX-WS, CFX, Axis. Стили WSDL +- Реализация веб-сервисов в Java. JAX-RPC, JAX-WS. Стили WSDL - Создание API и реализации веб-сервиса MailService. - Деплой и тестирование через SoapUI. From ec9318b8582eb9bb6060c824cb6eec90c8d5a637 Mon Sep 17 00:00:00 2001 From: Grigory Kislin Date: Tue, 26 Jul 2016 17:13:06 +0300 Subject: [PATCH 05/11] Initial checkin --- .gitignore | 9 +++ README.md | 7 ++ pom.xml | 44 +++++++++++ src/main/java/ru/javaops/masterjava/Main.java | 14 ++++ .../javaops/masterjava/matrix/MainMatrix.java | 23 ++++++ .../javaops/masterjava/matrix/MatrixUtil.java | 24 ++++++ .../masterjava/service/MailService.java | 75 +++++++++++++++++++ 7 files changed, 196 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 pom.xml create mode 100644 src/main/java/ru/javaops/masterjava/Main.java create mode 100644 src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java create mode 100644 src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java create mode 100644 src/main/java/ru/javaops/masterjava/service/MailService.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..530d0056a --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +.idea +out +target +*.iml +log +backup + + + diff --git a/README.md b/README.md new file mode 100644 index 000000000..54954b415 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +## Разработка полнофункционального многомодульного Maven проекта +- веб приложение (Tomcat, JSP, jQuery), +- многопоточный почтовый сервиса (JavaMail, java.util.concurrent.*) +- вспомогательные модули, связанных по веб-сервисам (SOAP, JAX-WS, Axis) и по REST (JAX-RS) +- сохранение данных в RMDBS и динамическое конфигурирование модулей по JMX. + +## Описание курса \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 000000000..39e811e08 --- /dev/null +++ b/pom.xml @@ -0,0 +1,44 @@ + + 4.0.0 + + ru.javaops + masterjava + jar + + 1.0-SNAPSHOT + + Master Java + https://github.com/JavaOPs/masterjava + + + 1.8 + UTF-8 + UTF-8 + + + + masterjava + install + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + ${java.version} + ${java.version} + + + + + + + + + + + + + + diff --git a/src/main/java/ru/javaops/masterjava/Main.java b/src/main/java/ru/javaops/masterjava/Main.java new file mode 100644 index 000000000..a849258c4 --- /dev/null +++ b/src/main/java/ru/javaops/masterjava/Main.java @@ -0,0 +1,14 @@ +package ru.javaops.masterjava; + +/** + * User: gkislin + * Date: 05.08.2015 + * + * @link http://caloriesmng.herokuapp.com/ + * @link https://github.com/JavaOPs/topjava + */ +public class Main { + public static void main(String[] args) { + System.out.format("Hello MasterJava!"); + } +} diff --git a/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java b/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java new file mode 100644 index 000000000..28f28dc9f --- /dev/null +++ b/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java @@ -0,0 +1,23 @@ +package ru.javaops.masterjava.matrix; + +/** + * gkislin + * 03.07.2016 + */ +public class MainMatrix { + // Multiplex matrix + private static final int MATRIX_SIZE = 1000; + private static final int THREAD_NUMBER = 10; + + public static void main(String[] args) { + final int[][] matrixA = new int[MATRIX_SIZE][MATRIX_SIZE]; + final int[][] matrixB = new int[MATRIX_SIZE][MATRIX_SIZE]; + + long start = System.currentTimeMillis(); + final int[][] matrixC = MatrixUtil.singleThreadMultiply(matrixA, matrixB); + System.out.println("Single thread multiplication time, sec: " + (System.currentTimeMillis() - start)/1000.); + + // TODO implement parallel multiplication matrixA*matrixB + // TODO compare wih matrixC; + } +} diff --git a/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java b/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java new file mode 100644 index 000000000..9e01a338b --- /dev/null +++ b/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java @@ -0,0 +1,24 @@ +package ru.javaops.masterjava.matrix; + +/** + * gkislin + * 03.07.2016 + */ +public class MatrixUtil { + + public static int[][] singleThreadMultiply(int[][] matrixA, int[][] matrixB) { + final int matrixSize = matrixA.length; + final int[][] matrixC = new int[matrixSize][matrixSize]; + + for (int i = 0; i < matrixSize; i++) { + for (int j = 0; j < matrixSize; j++) { + int sum = 0; + for (int k = 0; k < matrixSize; k++) { + sum += matrixA[i][k] * matrixB[k][j]; + } + matrixC[i][j] = sum; + } + } + return matrixC; + } +} diff --git a/src/main/java/ru/javaops/masterjava/service/MailService.java b/src/main/java/ru/javaops/masterjava/service/MailService.java new file mode 100644 index 000000000..3f9628e04 --- /dev/null +++ b/src/main/java/ru/javaops/masterjava/service/MailService.java @@ -0,0 +1,75 @@ +package ru.javaops.masterjava.service; + +import java.util.Collections; +import java.util.List; +import java.util.Set; + +public class MailService { + private static final String OK = "OK"; + + private static final String INTERRUPTED_BY_FAULTS_NUMBER = "+++ Interrupted by faults number"; + private static final String INTERRUPTED_BY_TIMEOUT = "+++ Interrupted by timeout"; + private static final String INTERRUPTED_EXCEPTION = "+++ InterruptedException"; + + public GroupResult sendToList(final String template, final Set emails) throws Exception { + return new GroupResult(0, Collections.emptyList(), null); + } + + + // dummy realization + public MailResult sendToUser(String template, String email) throws Exception { + try { + Thread.sleep(500); //delay + } catch (InterruptedException e) { + // log cancel; + return null; + } + return Math.random() < 0.7 ? MailResult.ok(email) : MailResult.error(email, "Error"); + } + + public static class MailResult { + private final String email; + private final String result; + + private static MailResult ok(String email) { + return new MailResult(email, OK); + } + + private static MailResult error(String email, String error) { + return new MailResult(email, error); + } + + public boolean isOk() { + return OK.equals(result); + } + + private MailResult(String email, String cause) { + this.email = email; + this.result = cause; + } + + @Override + public String toString() { + return '(' + email + ',' + result + ')'; + } + } + + public static class GroupResult { + private final int success; // number of successfully sent email + private final List failed; // failed emails with causes + private final String failedCause; // global fail cause + + public GroupResult(int success, List failed, String failedCause) { + this.success = success; + this.failed = failed; + this.failedCause = failedCause; + } + + @Override + public String toString() { + return "Success: " + success + '\n' + + "Failed: " + failed.toString() + '\n' + + (failedCause == null ? "" : "Failed cause" + failedCause); + } + } +} From 64d89954d45fadbbf7281de8f4827ac45eaee41e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9F=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D1=8B=20=D0=B2=20?= =?UTF-8?q?=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B5?= Date: Tue, 26 Jul 2016 17:50:55 +0300 Subject: [PATCH 06/11] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 54954b415..514a7de35 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ ## Разработка полнофункционального многомодульного Maven проекта + - веб приложение (Tomcat, JSP, jQuery), - многопоточный почтовый сервиса (JavaMail, java.util.concurrent.*) - вспомогательные модули, связанных по веб-сервисам (SOAP, JAX-WS, Axis) и по REST (JAX-RS) - сохранение данных в RMDBS и динамическое конфигурирование модулей по JMX. -## Описание курса \ No newline at end of file +## Описание курса From 6fdc3913cb8279e202334199ef28cd844647817f Mon Sep 17 00:00:00 2001 From: Grigory Kislin Date: Wed, 27 Jul 2016 13:43:42 +0300 Subject: [PATCH 07/11] Implement LazySingleton --- .../ru/javaops/masterjava/LazySingleton.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/main/java/ru/javaops/masterjava/LazySingleton.java diff --git a/src/main/java/ru/javaops/masterjava/LazySingleton.java b/src/main/java/ru/javaops/masterjava/LazySingleton.java new file mode 100644 index 000000000..1e4498317 --- /dev/null +++ b/src/main/java/ru/javaops/masterjava/LazySingleton.java @@ -0,0 +1,32 @@ +package ru.javaops.masterjava; + +/** + * gkislin + * 26.07.2016 + */ +public class LazySingleton { + private static LazySingleton instance; + private final int i; + + private static class LazyHolder { + private static final LazySingleton INSTANCE = new LazySingleton(); + } + + public static LazySingleton getInstance() { + return LazyHolder.INSTANCE; +/* + if (instance == null) { + synchronized (LazySingleton.class) { + if (instance == null) { + instance = new LazySingleton(); + } + } + } + return instance; +*/ + } + + private LazySingleton() { + i = 5 + 8; + } +} From bbabb4989296d87556cd86453e1c7984b548dbae Mon Sep 17 00:00:00 2001 From: Grigory Kislin Date: Wed, 27 Jul 2016 13:44:40 +0300 Subject: [PATCH 08/11] MailService multithread implementation --- .../masterjava/service/MailService.java | 72 ++++++++++++++++++- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/src/main/java/ru/javaops/masterjava/service/MailService.java b/src/main/java/ru/javaops/masterjava/service/MailService.java index 3f9628e04..c8fae6d6a 100644 --- a/src/main/java/ru/javaops/masterjava/service/MailService.java +++ b/src/main/java/ru/javaops/masterjava/service/MailService.java @@ -1,8 +1,10 @@ package ru.javaops.masterjava.service; -import java.util.Collections; +import java.util.ArrayList; import java.util.List; import java.util.Set; +import java.util.concurrent.*; +import java.util.stream.Collectors; public class MailService { private static final String OK = "OK"; @@ -11,10 +13,74 @@ public class MailService { private static final String INTERRUPTED_BY_TIMEOUT = "+++ Interrupted by timeout"; private static final String INTERRUPTED_EXCEPTION = "+++ InterruptedException"; + private final ExecutorService mailExecutor = Executors.newFixedThreadPool(8); + public GroupResult sendToList(final String template, final Set emails) throws Exception { - return new GroupResult(0, Collections.emptyList(), null); - } + final CompletionService completionService = new ExecutorCompletionService<>(mailExecutor); + + List> futures = emails.stream() + .map(email -> mailExecutor.submit(() -> sendToUser(template, email))) + .collect(Collectors.toList()); + return new Callable() { + private int success = 0; + private List failed = new ArrayList<>(); + + @Override + public GroupResult call() { + while (!futures.isEmpty()) { + try { + Future future = completionService.poll(10, TimeUnit.SECONDS); + if (future == null) { + return cancelWithFail(INTERRUPTED_BY_TIMEOUT); + } + futures.remove(future); + MailResult mailResult = future.get(); + if (mailResult.isOk()) { + success++; + } else { + failed.add(mailResult); + if (failed.size() >= 5) { + return cancelWithFail(INTERRUPTED_BY_FAULTS_NUMBER); + } + } + } catch (ExecutionException e) { + return cancelWithFail(e.getCause().toString()); + } catch (InterruptedException e) { + return cancelWithFail(INTERRUPTED_EXCEPTION); + } + } +/* + for (Future future : futures) { + MailResult mailResult; + try { + mailResult = future.get(10, TimeUnit.SECONDS); + } catch (InterruptedException e) { + return cancelWithFail(INTERRUPTED_EXCEPTION); + } catch (ExecutionException e) { + return cancelWithFail(e.getCause().toString()); + } catch (TimeoutException e) { + return cancelWithFail(INTERRUPTED_BY_TIMEOUT); + } + if (mailResult.isOk()) { + success++; + } else { + failed.add(mailResult); + if (failed.size() >= 5) { + return cancelWithFail(INTERRUPTED_BY_FAULTS_NUMBER); + } + } + } +*/ + return new GroupResult(success, failed, null); + } + + private GroupResult cancelWithFail(String cause) { + futures.forEach(f -> f.cancel(true)); + return new GroupResult(success, failed, cause); + } + }.call(); + } // dummy realization public MailResult sendToUser(String template, String email) throws Exception { From d5e7c5a85a3fd6a9374032d94e711bc542c10d0d Mon Sep 17 00:00:00 2001 From: Grigory Kislin Date: Wed, 7 Sep 2016 01:48:31 +0300 Subject: [PATCH 09/11] Prepare to Matrix implementation --- .../javaops/masterjava/matrix/MainMatrix.java | 44 +++++++++++++++---- .../javaops/masterjava/matrix/MatrixUtil.java | 33 ++++++++++++++ 2 files changed, 68 insertions(+), 9 deletions(-) diff --git a/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java b/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java index 28f28dc9f..832e847ec 100644 --- a/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java +++ b/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java @@ -1,23 +1,49 @@ package ru.javaops.masterjava.matrix; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + /** * gkislin * 03.07.2016 */ public class MainMatrix { - // Multiplex matrix private static final int MATRIX_SIZE = 1000; private static final int THREAD_NUMBER = 10; - public static void main(String[] args) { - final int[][] matrixA = new int[MATRIX_SIZE][MATRIX_SIZE]; - final int[][] matrixB = new int[MATRIX_SIZE][MATRIX_SIZE]; + private final static ExecutorService executor = Executors.newFixedThreadPool(MainMatrix.THREAD_NUMBER); + + public static void main(String[] args) throws ExecutionException, InterruptedException { + final int[][] matrixA = MatrixUtil.create(MATRIX_SIZE); + final int[][] matrixB = MatrixUtil.create(MATRIX_SIZE); + + double singleThreadSum = 0.; + double concurrentThreadSum = 0.; + for (int i = 0; i < 5; i++) { + long start = System.currentTimeMillis(); + final int[][] matrixC = MatrixUtil.singleThreadMultiply(matrixA, matrixB); + double duration = (System.currentTimeMillis() - start) / 1000.; + out("Single thread time, sec: %.3f", duration); + singleThreadSum += duration; - long start = System.currentTimeMillis(); - final int[][] matrixC = MatrixUtil.singleThreadMultiply(matrixA, matrixB); - System.out.println("Single thread multiplication time, sec: " + (System.currentTimeMillis() - start)/1000.); + start = System.currentTimeMillis(); + final int[][] concurrentMatrixC = MatrixUtil.concurrentMultiply(matrixA, matrixB, executor); + duration = (System.currentTimeMillis() - start) / 1000.; + out("Concurrent thread time, sec: %.3f", duration); + concurrentThreadSum += duration; + + if (!MatrixUtil.compare(matrixC, concurrentMatrixC)) { + System.err.println("Comparison failed"); + break; + } + } + executor.shutdown(); + out("\nAverage single thread time, sec: %.3f", singleThreadSum / 5.); + out("Average concurrent thread time, sec: %.3f", concurrentThreadSum / 5.); + } - // TODO implement parallel multiplication matrixA*matrixB - // TODO compare wih matrixC; + private static void out(String format, double ms) { + System.out.println(String.format(format, ms)); } } diff --git a/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java b/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java index 9e01a338b..316891526 100644 --- a/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java +++ b/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java @@ -1,11 +1,20 @@ package ru.javaops.masterjava.matrix; +import java.util.Random; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; + /** * gkislin * 03.07.2016 */ public class MatrixUtil { + // TODO implement parallel multiplication matrixA*matrixB + public static int[][] concurrentMultiply(int[][] matrixA, int[][] matrixB, ExecutorService executor) throws InterruptedException, ExecutionException { + return null; + } + public static int[][] singleThreadMultiply(int[][] matrixA, int[][] matrixB) { final int matrixSize = matrixA.length; final int[][] matrixC = new int[matrixSize][matrixSize]; @@ -21,4 +30,28 @@ public static int[][] singleThreadMultiply(int[][] matrixA, int[][] matrixB) { } return matrixC; } + + public static int[][] create(int size) { + int[][] matrix = new int[size][size]; + Random rn = new Random(); + + for (int i = 0; i < size; i++) { + for (int j = 0; j < size; j++) { + matrix[i][j] = rn.nextInt(10); + } + } + return matrix; + } + + public static boolean compare(int[][] matrixA, int[][] matrixB) { + final int matrixSize = matrixA.length; + for (int i = 0; i < matrixSize; i++) { + for (int j = 0; j < matrixSize; j++) { + if (matrixA[i][j] != matrixB[i][j]) { + return false; + } + } + } + return true; + } } From 25bb6a4b9ad78a45e6fa825c69da76dfec4453fb Mon Sep 17 00:00:00 2001 From: cuidadoso Date: Wed, 21 Sep 2016 21:02:34 +0700 Subject: [PATCH 10/11] Test task for multithreading online course. --- .../javaops/masterjava/matrix/MainMatrix.java | 8 +++ .../javaops/masterjava/matrix/MatrixUtil.java | 59 +++++++++++++++++-- 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java b/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java index 832e847ec..5f85d4970 100644 --- a/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java +++ b/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java @@ -19,6 +19,7 @@ public static void main(String[] args) throws ExecutionException, InterruptedExc final int[][] matrixB = MatrixUtil.create(MATRIX_SIZE); double singleThreadSum = 0.; + double singleThreadImprovedSum = 0.; double concurrentThreadSum = 0.; for (int i = 0; i < 5; i++) { long start = System.currentTimeMillis(); @@ -27,6 +28,12 @@ public static void main(String[] args) throws ExecutionException, InterruptedExc out("Single thread time, sec: %.3f", duration); singleThreadSum += duration; + start = System.currentTimeMillis(); + final int[][] improvedMatrixC = MatrixUtil.singleThreadMultiplyImproved(matrixA, matrixB); + duration = (System.currentTimeMillis() - start) / 1000.; + out("Single thread improved time, sec: %.3f", duration); + singleThreadImprovedSum += duration; + start = System.currentTimeMillis(); final int[][] concurrentMatrixC = MatrixUtil.concurrentMultiply(matrixA, matrixB, executor); duration = (System.currentTimeMillis() - start) / 1000.; @@ -40,6 +47,7 @@ public static void main(String[] args) throws ExecutionException, InterruptedExc } executor.shutdown(); out("\nAverage single thread time, sec: %.3f", singleThreadSum / 5.); + out("Average single thread improved time, sec: %.3f", singleThreadImprovedSum / 5.); out("Average concurrent thread time, sec: %.3f", concurrentThreadSum / 5.); } diff --git a/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java b/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java index 316891526..6b35ad93b 100644 --- a/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java +++ b/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java @@ -1,8 +1,9 @@ package ru.javaops.masterjava.matrix; +import java.util.ArrayList; +import java.util.List; import java.util.Random; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; +import java.util.concurrent.*; /** * gkislin @@ -11,8 +12,38 @@ public class MatrixUtil { // TODO implement parallel multiplication matrixA*matrixB - public static int[][] concurrentMultiply(int[][] matrixA, int[][] matrixB, ExecutorService executor) throws InterruptedException, ExecutionException { - return null; + public static int[][] concurrentMultiply(final int[][] matrixA, final int[][] matrixB, final ExecutorService executor) throws InterruptedException, ExecutionException { + + final int matrixSize = matrixA.length; + final int[][] matrixC = new int[matrixSize][matrixSize]; + + List> taskList = new ArrayList<>(); + + for (int i = 0; i < matrixSize; i++) { + final int i2 = i; + for (int j = 0; j < matrixSize; j++) { + final int j2 = j; + taskList.add(() -> + { + int sum = 0; + for (int k = 0; k < matrixSize; k++) { + sum += matrixA[i2][k] * matrixB[k][j2]; + } + matrixC[i2][j2] = sum; + return true; + }); + /*executor.submit(() -> + { + int sum = 0; + for (int k = 0; k < matrixSize; k++) { + sum += matrixA[i2][k] * matrixB[k][j2]; + } + matrixC[i2][j2] = sum; + });*/ + } + } + executor.invokeAll(taskList); + return matrixC; } public static int[][] singleThreadMultiply(int[][] matrixA, int[][] matrixB) { @@ -31,6 +62,26 @@ public static int[][] singleThreadMultiply(int[][] matrixA, int[][] matrixB) { return matrixC; } + public static int[][] singleThreadMultiplyImproved(int[][] matrixA, int[][] matrixB) { + final int matrixSize = matrixA.length; + final int[][] matrixC = new int[matrixSize][matrixSize]; + int thatColumn[] = new int[matrixSize]; + for (int j = 0; j < matrixSize; j++) { + for (int k = 0; k < matrixSize; k++) { + thatColumn[k] = matrixB[k][j]; + } + for (int i = 0; i < matrixSize; i++) { + int thisRow[] = matrixA[i]; + int sum = 0; + for (int k = 0; k < matrixSize; k++) { + sum += thisRow[k] * thatColumn[k]; + } + matrixC[i][j] = sum; + } + } + return matrixC; + } + public static int[][] create(int size) { int[][] matrix = new int[size][size]; Random rn = new Random(); From 06b49a532664c843c57466e9a8781b0e289a2759 Mon Sep 17 00:00:00 2001 From: cuidadoso Date: Wed, 21 Sep 2016 23:18:08 +0700 Subject: [PATCH 11/11] Add method concurrentMultiplyImproved. --- .../javaops/masterjava/matrix/MainMatrix.java | 9 ++++++ .../javaops/masterjava/matrix/MatrixUtil.java | 30 +++++++++++++++---- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java b/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java index 5f85d4970..5cbe46326 100644 --- a/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java +++ b/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java @@ -21,7 +21,9 @@ public static void main(String[] args) throws ExecutionException, InterruptedExc double singleThreadSum = 0.; double singleThreadImprovedSum = 0.; double concurrentThreadSum = 0.; + double concurrentImprovedThreadSum = 0.; for (int i = 0; i < 5; i++) { + long start = System.currentTimeMillis(); final int[][] matrixC = MatrixUtil.singleThreadMultiply(matrixA, matrixB); double duration = (System.currentTimeMillis() - start) / 1000.; @@ -40,6 +42,12 @@ public static void main(String[] args) throws ExecutionException, InterruptedExc out("Concurrent thread time, sec: %.3f", duration); concurrentThreadSum += duration; + start = System.currentTimeMillis(); + final int[][] concurrentImprovedMatrixC = MatrixUtil.concurrentMultiplyImproved(matrixA, matrixB, executor); + duration = (System.currentTimeMillis() - start) / 1000.; + out("Concurrent thread improved time, sec: %.3f", duration); + concurrentImprovedThreadSum += duration; + if (!MatrixUtil.compare(matrixC, concurrentMatrixC)) { System.err.println("Comparison failed"); break; @@ -49,6 +57,7 @@ public static void main(String[] args) throws ExecutionException, InterruptedExc out("\nAverage single thread time, sec: %.3f", singleThreadSum / 5.); out("Average single thread improved time, sec: %.3f", singleThreadImprovedSum / 5.); out("Average concurrent thread time, sec: %.3f", concurrentThreadSum / 5.); + out("Average concurrent thread improved time, sec: %.3f", concurrentImprovedThreadSum / 5.); } private static void out(String format, double ms) { diff --git a/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java b/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java index 6b35ad93b..8d339b728 100644 --- a/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java +++ b/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java @@ -11,14 +11,11 @@ */ public class MatrixUtil { - // TODO implement parallel multiplication matrixA*matrixB public static int[][] concurrentMultiply(final int[][] matrixA, final int[][] matrixB, final ExecutorService executor) throws InterruptedException, ExecutionException { final int matrixSize = matrixA.length; final int[][] matrixC = new int[matrixSize][matrixSize]; - List> taskList = new ArrayList<>(); - for (int i = 0; i < matrixSize; i++) { final int i2 = i; for (int j = 0; j < matrixSize; j++) { @@ -32,14 +29,35 @@ public static int[][] concurrentMultiply(final int[][] matrixA, final int[][] ma matrixC[i2][j2] = sum; return true; }); - /*executor.submit(() -> + } + } + executor.invokeAll(taskList); + return matrixC; + } + + public static int[][] concurrentMultiplyImproved(final int[][] matrixA, final int[][] matrixB, final ExecutorService executor) throws InterruptedException, ExecutionException { + + final int matrixSize = matrixA.length; + final int[][] matrixC = new int[matrixSize][matrixSize]; + int thatColumn[] = new int[matrixSize]; + List> taskList = new ArrayList<>(); + for (int j = 0; j < matrixSize; j++) { + final int j2 = j; + for (int k = 0; k < matrixSize; k++) { + thatColumn[k] = matrixB[k][j]; + } + for (int i = 0; i < matrixSize; i++) { + final int i2 = i; + int thisRow[] = matrixA[i]; + taskList.add(() -> { int sum = 0; for (int k = 0; k < matrixSize; k++) { - sum += matrixA[i2][k] * matrixB[k][j2]; + sum += thisRow[k] * thatColumn[k]; } matrixC[i2][j2] = sum; - });*/ + return true; + }); } } executor.invokeAll(taskList);