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..e05a40abd 100644
--- a/README.md
+++ b/README.md
@@ -1,42 +1,129 @@
-#### Написание с нуля полнофункционального многомодульного Maven проекта:
-веб приложения (Tomcat, JSP, jQuery),
-многопоточного почтового сервиса (JavaMail, java.util.concurrent.*) и вспомогательных модулей связанных по Веб и REST сервисам (SOAP, JAX-WS, Axis, JAX-RS)
-c сохранением данных в RMDBS и динамическим конфигурирование модулей по JMX.
+# Многопоточность. XML. Веб сервисы
+## Регистрация на проект
-## Сервис-ориентированная архитектура, Микросервисы
+### _Разработка полнофункционального многомодульного Maven проекта_
+- веб приложение (Tomcat, JSP, jQuery)
+- многопоточный почтовый сервиса (JavaMail, java.util.concurrent.*) и вспомогательные модули
+- связь модулей через веб-сервисы (SOAP, JAX-WS) и по REST (JAX-RS)
+- сохранение данных в RMDBS (H2) и динамическое конфигурирование модулей по JMX.
+
+### Требование к участникам
+Опыт программирования на Java. Базовые знания Maven.
+
+## Необходимое ПО
+- JDK8
+- Git
+- IntelliJ IDEA
+
+> Выбирать Ultimate, 30 days trial (работа с JavaScript, Tomcat, JSP). Учебный ключ к Ultimate выдается на первом занятии.
+
+# Первое занятие: многопоточность.
+
+##  1. Вступление. Многопоточность и параллельность.
+
+
+##  2. Структура памяти Java. Ленивая инициализация.
+
+### Структура памяти: куча, стек, permanent/metaspace
+ - JVM изнутри - оптимизация и профилирование.
+ - Stack and Heap
+ - Дополнительно:
+ - Из каких частей состоит память java процесса.
+ - Permanent область памяти
+ - Java thread stack
+ - Размер Java объектов
+
+### Ленивая инициализация
+- Реализация Singleton в JAVA
+- Double checked locking
+- Initialization-on-demand holder idiom
+- Реализация Singleton в JAVA
+
+##  3. Реализация многопоточности в Java
+- Параллелизм в Java
+- Монитор (синхронизация)
+- Compare-and-swap
+- Java Memory Model
+- Синхронизация потоков
+- Обзор java.util.concurrent.*
+- Как работает ConcurrentHashMap
+- Справочник по синхронизаторам java.util.concurrent.*
+- Использование ThreadLocal переменных
+- Николай Алименков — Прикладная многопоточность
+- Can thread switching happen in the synchronized block?
+
+##  4. Реализация многопоточной отправки писем. Execution Framework
+
+----------------------------
+
+### Ресурсы (основы)
+- Intuit, Потоки выполнения. Синхронизация
+- Алексей Владыкин, Основы многопоточность в Java
+- Виталий Чибриков, Java. Многопоточность
+- Computer Science Center, курс Параллельное программирование
+- Юрий Ткач, курс Advanced Java - Concurrency
+- Головач, курс Java Multithreading
+
+---
+#  Вступительное задание
+
+Вычекать этот проект:
+```git clone https://github.com/JavaOPs/masterjava.git```
+
+Реализовать метод `MatrixUtil.concurrentMultiply`, позволяющий многопоточно перемножать квадратные матрицы N*N.
+- Количество дочерних потоков ограничено `MainMatrix.THREAD_NUMBER`.
+- Учесть что-нибудь из оптимизации
+
+-----
+# Программа курса
+> **возможны изменения, окончательная программа будет перед стартом курса**
+
+### Concurrent and Parallel Programming
+- Thread safety. Java Memory Model/ JSR 133. Happens-before.
+- Публикация объектов. Использование ThreadLocal переменных
+- Initialization on demand holder / Double-checked locking
+- Обзор java.util.concurrent.*
+
+### Microbenchmarking JMH
+
+### XML технологии
+- формат XML. XSD, XPath, XSL(T)
+- Java API for XML: DOM, SAX, StAX, XSLT
+
+### Сервис-ориентированная архитектура, Микросервисы
- JMS, альтернативы
- Варианты разворачивания сервисов. Работа с базой. Связывание сервисов.
-## Maven. Многомодульный Maven проект
+### Maven. Многомодульный Maven проект
- Build Lifecycle
- Dependency Mechanism
- Зависимости, профили, написание плагина
- The Reactor. Snapshots
-## Создание/тестирование веб-приложения.
+### Создание/тестирование веб-приложения.
- Сборка, запуск, локальный и удаленный debug проекта, способы деплоя в Tomcat
- tomcat7-maven-plugin
### Веб-сервисы
- Веб-сервисы. SOAP. Преимущества/недостатки веб-сервисов. Расширения.
-- Реализация веб-сервисов в Java. JAX-RPC, JAX-WS, CFX, Axis. Стили WSDL
+- Реализация веб-сервисов в Java. JAX-RPC, JAX-WS. Стили WSDL
- Создание 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 +131,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..832e847ec
--- /dev/null
+++ b/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java
@@ -0,0 +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 {
+ private static final int MATRIX_SIZE = 1000;
+ private static final int THREAD_NUMBER = 10;
+
+ 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;
+
+ 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.);
+ }
+
+ 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
new file mode 100644
index 000000000..316891526
--- /dev/null
+++ b/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java
@@ -0,0 +1,57 @@
+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];
+
+ 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;
+ }
+
+ 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;
+ }
+}
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..2b6aeb294
--- /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);
+ }
+ }
+}
\ No newline at end of file