diff --git a/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java b/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java index 80a344a..e150062 100644 --- a/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java +++ b/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java @@ -1,7 +1,9 @@ package ru.javaops.masterjava.matrix; import java.util.Random; +import java.util.concurrent.CompletionService; import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorCompletionService; import java.util.concurrent.ExecutorService; /** @@ -9,12 +11,70 @@ * 03.07.2016 */ public class MatrixUtil { + static class Processor { + + private int[] matrixA; + private int[] matrixB; + + public Processor(int[] matrixA, int[] matrixB) { + this.matrixA = matrixA; + this.matrixB = matrixB; + } + + public static int[] mult(int[] matrixA, int[] matrixB) { + int[] matrixC = new int[matrixA.length]; + for (int i = 0; i < matrixA.length; i++) { + matrixC[i] = matrixA[i] * matrixB[i]; + } + return matrixC; + } + } // TODO implement parallel multiplication matrixA*matrixB public static int[][] concurrentMultiply(int[][] matrixA, int[][] matrixB, ExecutorService executor) throws InterruptedException, ExecutionException { final int matrixSize = matrixA.length; final int[][] matrixC = new int[matrixSize][matrixSize]; + class ColumnMultResult { + private final int col; + private final int[] columnC; + + private ColumnMultResult(int col, int[] columnC) { + this.col = col; + this.columnC = columnC; + } + } + + final CompletionService completionService = new ExecutorCompletionService<>(executor); + + for (int i = 0; i < matrixSize; i++) { + final int col = i; + final int[] colB = new int[matrixSize]; + for (int j = 0; j < matrixSize; j++) { + colB[j] = matrixB[j][i]; + } + completionService.submit(() -> { + final int[] columResult = new int[matrixSize]; + + for (int j = 0; j < matrixSize; j++) { + final int[] columnA = matrixA[j]; + int sum = 0; + for (int k = 0; k < matrixSize; k++) { + sum += colB[k] * columnA[k]; + } + columResult[j] = sum; + } + + return new ColumnMultResult(col, columResult); + }); + } + for (int j = 0; j < matrixSize; j++) { + ColumnMultResult res = completionService.take().get(); + for (int k = 0; k < matrixSize; k++) { + matrixC[k][res.col] = res.columnC[k]; + } + } + return matrixC; } @@ -22,15 +82,29 @@ public static int[][] concurrentMultiply(int[][] matrixA, int[][] matrixB, Execu public static int[][] singleThreadMultiply(int[][] matrixA, int[][] matrixB) { final int matrixSize = matrixA.length; final int[][] matrixC = new int[matrixSize][matrixSize]; + final int aColumns = matrixA.length; + final int aRows = matrixA[0].length; + final int bColumns = matrixB.length; + final int bRows = matrixB[0].length; - 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]; + double thatColumn[] = new double[bRows]; + + try { + for (int j = 0; ; j++) { + for (int k = 0; k < aColumns; k++) { + thatColumn[k] = matrixB[k][j]; + } + + for (int i = 0; i < aRows; i++) { + int thisRow[] = matrixA[i]; + int summand = 0; + for (int k = 0; k < aColumns; k++) { + summand += thisRow[k] * thatColumn[k]; + } + matrixC[i][j] = summand; } - matrixC[i][j] = sum; } + } catch (IndexOutOfBoundsException ignored) { } return matrixC; } diff --git a/src/main/java/ru/javaops/masterjava/service/MailService.java b/src/main/java/ru/javaops/masterjava/service/MailService.java index 2b6aeb2..cef46e5 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 -> completionService.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 {