Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hw1 #5

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 17 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
- используя асинхронные сервлеты 3.0
- сохранение данных в PostgreSQL используя [jDBI](http://jdbi.org/)
- миграция базы [LiquiBase](http://www.liquibase.org/)
- использование в проекте [Guava](https://github.com/google/guava/wiki), [Thymleaf](http://www.thymeleaf.org/), [Lombook](https://projectlombok.org/), [StreamEx](https://github.com/amaembo/streamex),
- использование в проекте [Guava](https://github.com/google/guava/wiki), [Thymleaf](http://www.thymeleaf.org/), [Lombok](https://projectlombok.org/), [StreamEx](https://github.com/amaembo/streamex),
[Typesafe Config](https://github.com/typesafehub/config), [Java Microbenchmark JMH](http://openjdk.java.net/projects/code-tools/jmh)

### Требование к участникам
Expand All @@ -38,13 +38,16 @@
> В видео в `LazySingleton` ошибка: должно быть как в коде проекта `instance == null`

### Структура памяти: куча, стек, permanent/metaspace
- <a href="https://www.slideshare.net/solit/jvm-16948708">JVM изнутри - оптимизация и профилирование</a>.
- <a href="https://documents.tips/technology/jvm-.html">JVM изнутри - оптимизация и профилирование</a>.
- <a href="http://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap#24171266">Stack and Heap</a>
- Дополнительно:
- <a href="http://habrahabr.ru/post/117274/">Из каких частей состоит память java процесса</a>.
- <a href="http://www.javaspecialist.ru/2011/04/permanent.html">Permanent область памяти</a>
- <a href="http://www.javaspecialist.ru/2011/04/java-thread-stack.html">Java thread stack </a>
- <a href="http://habrahabr.ru/post/134102/">Размер Java объектов</a>
- Оптимизация памяти
- [Escape analysis и скаляризация: Пусть GC отдохнет](https://habr.com/company/jugru/blog/322348)
- [Условия для размещения объекта в стеке](https://stackoverflow.com/a/43002529/548473)

### Ленивая инициализация
- <a href="https://habrahabr.ru/post/27108/">Реализация Singleton в JAVA</a>
Expand All @@ -64,6 +67,7 @@
- <a href="http://articles.javatalks.ru/articles/17">Использование ThreadLocal переменных</a>
- <a href="https://www.youtube.com/watch?v=8piqauDj2yo">Николай Алименков — Прикладная многопоточность</a>
- <a href="http://stackoverflow.com/questions/20163056/in-java-can-thread-switching-happen-in-the-synchronized-block">Can thread switching happen in the synchronized block?</a>
- [Реактивное программирование - как, зачем и стоит ли?](https://habr.com/ru/company/oleg-bunin/blog/543386/)

#### Tproger: Многопоточное программирование в Java 8
- <a href="https://tproger.ru/translations/java8-concurrency-tutorial-1/">1. Параллельное выполнение кода с помощью потоков</a>
Expand All @@ -74,9 +78,10 @@
> правка к видео: `22: completionService.submit(..)`

### ![](https://cloud.githubusercontent.com/assets/13649199/13672935/ef09ec1e-e6e7-11e5-9f79-d1641c05cbe6.png) Все изменения в проекте будут делаться на основе патчей
#### Скачайте [1_1_MailService.patch](https://drive.google.com/open?id=0B9Ye2auQ_NsFTE5ZV3pzWElxTWM), положите его в проект, правой мышкой на нем сделайте Apply Patch ...
#### Скачайте [1_1_MailService.patch](https://drive.google.com/file/d/0B9Ye2auQ_NsFTE5ZV3pzWElxTWM/view?resourcekey=0-TF7H5aadPlE3aQukNC5Ejg), положите его в проект, правой мышкой на нем сделайте Apply Patch ...

----------------------------
- [Как сделать Java код проще и нагляднее](https://habrahabr.ru/company/wrike/blog/349652/)

### Ресурсы (основы)
- Intuit, <a href="http://www.intuit.ru/studies/courses/16/16/lecture/27127">Потоки выполнения. Синхронизация</a>
Expand All @@ -85,23 +90,26 @@
- Computer Science Center, курс <a href="https://compscicenter.ru/courses/hp-course/2016-spring">Параллельное программирование</a>
- Юрий Ткач, курс <a href="https://www.youtube.com/playlist?list=PL6jg6AGdCNaXo06LjCBmRao-qJdf38oKp">Advanced Java - Concurrency</a>
- Головач, курс <a href="https://www.youtube.com/playlist?list=PLoij6udfBncgVRq487Me6yQa1kqtxobZS">Java Multithreading</a>

- [Перевод «Java Memory Model»](https://habr.com/ru/post/510454/)
---
## ![hw](https://cloud.githubusercontent.com/assets/13649199/13672719/09593080-e6e7-11e5-81d1-5cb629c438ca.png) Задание первого занятия

Вычекать этот проект:
```git clone https://github.com/JavaOPs/masterjava.git```

> - [Настройка git на свой репозиторий](https://github.com/JavaOPs/basejava/blob/master/lesson/lesson1.md#настройка-проекта)
> - [Правила работы с патчами на проекте](https://github.com/JavaOPs/topjava/wiki/Git)

- Применить <a href="https://habrahabr.ru/post/114797/">оптимизацию</a> к MatrixUtil.singleThreadMultiply
- Реализовать метод `MatrixUtil.concurrentMultiply`, позволяющий многопоточно <a href="https://ru.wikipedia.org/wiki/Умножение_матриц">перемножать квадратные матрицы N*N</a>.
- Количество дочерних потоков ограничено `MainMatrix.THREAD_NUMBER`.
- Добиться того, чтобы на матрице 1000*1000 многопоточная реализация была быстрее однопоточной

-----
## ![error](https://cloud.githubusercontent.com/assets/13649199/13672935/ef09ec1e-e6e7-11e5-9f79-d1641c05cbe6.png) Подсказки по HW1
- не делайте 1000 000 тасок, лучше их сделать крупнее
- у меня разница между 4 и 1000 тасками по времени незаметна, поэтому делайте просто и не делайте сложно
- наконец: можно не считать значение элемента результирующей матрицы C за раз, а накапливать (`concurrentMultiply3`). Мои результаты:
- 1: не делайте 1000 000 тасок, лучше их сделать крупнее
- 2: у меня разница между 4 и 1000 тасками по времени незаметна, поэтому делайте просто и не делайте сложно
- 3: наконец: можно не считать значение элемента результирующей матрицы C за раз, а накапливать (`concurrentMultiply3`). Тогда трансформация B не нужна. Мои результаты:
```
Benchmark (matrixSize) Mode Cnt Score Error Units
MatrixBenchmark.singleThreadMultiplyOpt 1000 ss 100 837,867 ± 25,530 ms/op
Expand Down Expand Up @@ -134,14 +142,14 @@ MatrixBenchmark.concurrentMultiply3 1000 ss 100 186,827 ± 11,882
- Maven. Поиск и разрешение конфликтов зависимостей
- Подключаем логирование с общими настройкам
- Библиотеки и фреймворки для работы с JDBC.
- Модуль persist
- Модуль persistence

## Занятие 5
- Разбор ДЗ
- Сохранение в базу в batch-моде с обработкой конфликтов
- Вставка в несколько потоков
- Конфигурирование приложения (<a href="https://github.com/typesafehub/config">Typesafe config</a>)
- Lombook
- Lombok

## Занятие 6
- Разбор ДЗ (доработка модели и модуля export)
Expand Down
21 changes: 16 additions & 5 deletions src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,30 @@ public static int[][] concurrentMultiply(int[][] matrixA, int[][] matrixB, Execu
return matrixC;
}

// TODO optimize by https://habrahabr.ru/post/114797/
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++) {

int[] thatColumn = new int[matrixSize];

try {
for (int j = 0; j < matrixSize; j++) {
int sum = 0;
for (int k = 0; k < matrixSize; k++) {
sum += matrixA[i][k] * matrixB[k][j];
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;

}
matrixC[i][j] = sum;
}
} catch (IndexOutOfBoundsException ignored) {
}
return matrixC;
}
Expand Down
72 changes: 69 additions & 3 deletions src/main/java/ru/javaops/masterjava/service/MailService.java
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -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<String> emails) throws Exception {
return new GroupResult(0, Collections.emptyList(), null);
}
final CompletionService<MailResult> completionService = new ExecutorCompletionService<>(mailExecutor);

List<Future<MailResult>> futures = emails.stream()
.map(email -> completionService.submit(() -> sendToUser(template, email)))
.collect(Collectors.toList());

return new Callable<GroupResult>() {
private int success = 0;
private List<MailResult> failed = new ArrayList<>();

@Override
public GroupResult call() {
while (!futures.isEmpty()) {
try {
Future<MailResult> 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<MailResult> 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 {
Expand Down