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 выдается на первом занятии. + +# Первое занятие: многопоточность. + +## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 1. Вступление. Многопоточность и параллельность. +![Concurrent vs Parallel](https://joearms.github.io/images/con_and_par.jpg) + +## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 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 + +## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 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? + +## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 4. Реализация многопоточной отправки писем. Execution Framework + +---------------------------- + +### Ресурсы (основы) +- Intuit, Потоки выполнения. Синхронизация +- Алексей Владыкин, Основы многопоточность в Java +- Виталий Чибриков, Java. Многопоточность +- Computer Science Center, курс Параллельное программирование +- Юрий Ткач, курс Advanced Java - Concurrency +- Головач, курс Java Multithreading + +--- +# ![hw](https://cloud.githubusercontent.com/assets/13649199/13672719/09593080-e6e7-11e5-81d1-5cb629c438ca.png) Вступительное задание + +Вычекать этот проект: +```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