SlideShare a Scribd company logo
1 of 100
Download to read offline
От Java Threads к лямбдам
Андрей Родионов
@AndriiRodionov
http://jug.ua/
The Green Project
The Star7 PDA
• SPARC based, handheld wireless PDA
• with a 5" color LCD with touchscreen
input
• a new 16 bit color hardware double
buffered NTSC framebuffer
• 900MHz wireless networking
• multi-media audio codec
• a new power supply/battery
interface
• a version of Unix (SolarisOs) that
runs in under a megabyte including
drivers for PCMCIA
• radio networking
• flash RAM file system
+ Оак
• a new small, safe, secure, distributed, robust,
interpreted, garbage collected, multi-threaded,
architecture neutral, high performance,
dynamic programming language
• a set of classes that implement a spatial user
interface metaphor, a user interface
methodology which uses animation, audio,
spatial cues, gestures
• All of this, in 1992!
Зачем это все?
• Если Oak предназначался для подобных
устройств, когда еще было не особо много
многопроцессорных машин (и тем более
никто не мечтала о телефоне с 4 ядрами),
то зачем он изначально содержал
поддержку потоков???
Напишем реализации одной и той же
задачи с использованием
• Sequential algorithm
• Java Threads
• java.util.concurrent (Thread pool)
• Fork/Join
• Java 8 Stream API (Lambda)
А так же …
• Сравним производительность каждого из
подходов
MicroBenchmarking?!
Вы занимаетесь
микробенчмаркингом?
Тогда мы идем к Вам!
(The Art Of) (Java) Benchmarking
http://shipilev.net/
http://openjdk.java.net/projects/code-tools/jmh/
JMH is a Java harness for building, running, and analysing
nano/micro/milli/macro benchmarks written in Java and other
languages targetting the JVM.
В качестве задачи –
численное интегрирование
• Методом прямоугольников
Sequential algorithm
Sequential v.1
public class SequentialCalculate {
public double calculate(double start, double end,
double step) {
double result = 0.0;
double x = start;
while (x < end) {
result +=
step * (sin(x) * sin(x) + cos(x) * cos(x));
x += step;
}
return result;
}
}
Sequential v.1
public class SequentialCalculate {
public double calculate(double start, double end,
double step) {
double result = 0.0;
double x = start;
while (x < end) {
result +=
step * (sin(x) * sin(x) + cos(x) * cos(x));
x += step;
}
return result;
}
}
Sequential v.2: with Functional interface
public interface Function<T, R> {
R apply(T t);
}
Sequential v.2: with Functional interface
public interface Function<T, R> {
R apply(T t);
}
public class SequentialCalculate {
private final Function<Double, Double> func;
public SequentialCalculate(Function<Double, Double> func) {
this.func = func;
}
public double calculate(double start, double end,
double step) {
double result = 0.0;
double x = start;
while (x < end) {
result += step * func.apply(x);
x += step;
}
return result;
}
}
Sequential v.2
With Functional interface
SequentialCalculate sc = new SequentialCalculate (
new Function<Double, Double>() {
public Double apply(Double x) {
return sin(x) * sin(x) + cos(x) * cos(x);
}
}
);
Performance
• Intel Core i7-4770, 3.4GHz, 4 Physical cores + 4
Hyper threading = 8 CPUs
• Sun UltraSPARC T1, 1.0GHz, 8 Physical cores *
4 Light Weight Processes = 32 CPUs
54,832
1,877
0 10 20 30 40 50 60
t, sec
Java Threads
Как будем параллелить?
Thread 1 Thread 2 Thread N

class CalcThread extends Thread {
private final double start;
private final double end;
private final double step;
private double partialResult;
public CalcThread(double start, double end,
double step) {
this.start = start;
this.end = end;
this.step = step;
}
public void run() {
double x = start;
while (x < end) {
partialResult += step * func.apply(x);
x += step;
}
}
}
public double calculate(double start, double end,
double step, int chunks) {
CalcThread[] calcThreads = new CalcThread[chunks];
double interval = (end - start) / chunks;
double st = start;
for (int i = 0; i < chunks; i++) {
calcThreads[i] =
new CalcThread(st, st + interval, step);
calcThreads[i].start();
st += interval;
}
double result = 0.0;
for (CalcThread cs : calcThreads) {
cs.join();
result += cs.partialResult;
}
return result;
}
Spliterator
Collector
public double calculate(double start, double end,
double step, int chunks) {
CalcThread[] calcThreads = new CalcThread[chunks];
double interval = (end - start) / chunks;
double st = start;
for (int i = 0; i < chunks; i++) {
calcThreads[i] =
new CalcThread(st, st + interval, step);
calcThreads[i].start();
st += interval;
}
double result = 0.0;
for (CalcThread cs : calcThreads) {
cs.join();
result += cs.partialResult;
}
return result;
}
0
0,5
1
1,5
2
1 2 4 8 16 32
t(sec)
Threads
Execution time
Simple Threads
0
1
2
3
4
5
6
2 4 8 16 32
Speedup
Threads
Speedup
Simple Threads
Ограничения классического
подхода
• "поток-на-задачу" хорошо работает с небольшим
количеством долгосрочных задач
• слияние низкоуровневого кода, отвечающего за
многопоточное исполнение, и высокоуровневого
кода, отвечающего за основную функциональность
приложения приводит к т.н. «спагетти-коду»
• трудности связанные с управлением потоками
• поток занимает относительно много места в
памяти ~ 1 Mb
• для выполнения новой задачи потребуется
запустить новый поток – это одна из самых
требовательных к ресурсам операций
java.util.concurrent
Thread pool
• Пул потоков - это очередь в сочетании с
фиксированной группой рабочих потоков, в
которой используются wait() и notify(), чтобы
сигнализировать ожидающим потокам, что
прибыла новая работа.
class CalcThread implements Callable<Double> {
private final double start;
private final double end;
private final double step;
public CalcThread(double start, double end, double step){
this.start = start;
this.end = end;
this.step = step;
}
public Double call() {
double partialResult = 0.0;
double x = start;
while (x < end) {
partialResult += step * func.apply(x);
x += step;
}
return partialResult;
}
}
public double calculate(double start, double end,
double step, int chunks) {
ExecutorService executorService =
Executors.newFixedThreadPool(chunks);
Future<Double>[] futures = new Future[chunks];
double interval = (end - start) / chunks;
double st = start;
for (int i = 0; i < chunks; i++) {
futures[i] = executorService.submit(
new CalcThread(st, st + interval, step));
st += interval;
}
executorService.shutdown();
double result = 0.0;
for (Future<Double> partRes : futures) {
result += partRes.get();
}
return result;
}
public double calculate(double start, double end,
double step, int chunks) {
ExecutorService executorService =
Executors.newFixedThreadPool(chunks);
Future<Double>[] futures = new Future[chunks];
double interval = (end - start) / chunks;
double st = start;
for (int i = 0; i < chunks; i++) {
futures[i] = executorService.submit(
new CalcThread(st, st + interval, step));
st += interval;
}
executorService.shutdown();
double result = 0.0;
for (Future<Double> partRes : futures) {
result += partRes.get();
}
return result;
}
Spliterator
Collector
0
0,5
1
1,5
2
1 2 4 8 16 32
t(sec)
Threads
Execution time
Simple Threads
Thread Pool
0
1
2
3
4
5
6
2 4 8 16 32
Speedup
Threads
Speedup
Simple Threads Thread Pool
«Бытие определяет сознание»
Доминирующие в текущий момент аппаратные
платформы формируют подход к созданию языков,
библиотек и систем
• С самого момента зарождения языка в Java была
поддержка потоков и параллелизма (Thread,
synchronized, volatile, …)
• Однако примитивы параллелизма, введенные в 1995
году, отражали реальность аппаратного обеспечения
того времени: большинство доступных коммерческих
систем вообще не предоставляли возможностей
использования параллелизма, и даже наиболее
дорогостоящие системы предоставляли такие
возможности лишь в ограниченных масштабах
• В те дни потоки использовались в основном, для
выражения asynchrony, а не concurrency, и в результате,
эти механизмы в целом отвечали требованиям времени
Путь к параллелизму
• По мере изменения доминирующей аппаратной платформы,
должна соответственно изменяться и программная платформа
• Когда начался процесс удешевления многопроцессорных систем,
от приложений стали требовать все большего использования
предоставляемого системами аппаратного параллелизма. Тогда
программисты обнаружили, что разрабатывать параллельные
программы, использующие низкоуровневые примитивы,
обеспечиваемые языком и библиотекой классов, сложно и
чревато ошибками
• java.util.concurrent дала возможности для «coarse-grained»
параллелизма (поток на запрос), но этого может быть не
достаточно, т.к. сам по себе запрос может выполняться долго
• Необходимы средства для «finer-grained» параллелизма
Web server
Th1 Th2 Th3 ThNcoarse-grained parallelism
finer-grained parallelism
Fork/Join
Fork/Join
// PSEUDOCODE
Result solve(Problem problem) {
if (problem.size < SEQUENTIAL_THRESHOLD)
return solveSequentially(problem);
else {
Result left, right;
INVOKE-IN-PARALLEL {
left = solve(extractLeftHalf(problem));
right = solve(extractRightHalf(problem));
}
return combine(left, right);
}
}
• Fork/Join сейчас является одной из самых
распространённых методик для построения
параллельных алгоритмов
Work stealing - планировщики на
основе захвата работы
ForkJoinPool может в небольшом
количестве потоков выполнить
существенно большее число задач
Work stealing
• Планировщики на основе захвата работы (work
stealing) "автоматически" балансируют нагрузку за
счёт того, что потоки, оказавшиеся без задач,
самостоятельно обнаруживают и забирают
"свободные" задачи у других потоков. Находится ли
поток-"жертва" в активном или пассивном
состоянии, неважно.
• Основными преимуществами перед
планировщиком с общим пулом задач:
– отсутствие общего пула :), то есть точки глобальной
синхронизации
– лучшая локальность данных, потому что в большинстве
случаев поток самостоятельно выполняет
порождённые им задачи
public class ForkJoinCalculate extends RecursiveTask<Double> {
...
static final long SEQUENTIAL_THRESHOLD = 500;
...
@Override
protected Double compute() {
if ((end - start) / step < SEQUENTIAL_THRESHOLD) {
return sequentialCompute();
}
double mid = start + (end - start) / 2.0;
ForkJoinCalculate left =
new ForkJoinCalculate(func, start, mid, step);
ForkJoinCalculate right =
new ForkJoinCalculate(func, mid, end, step);
left.fork();
double rightAns = right.compute();
double leftAns = left.join();
return leftAns + rightAns;
}
}
protected double sequentialCompute() {
double x = start;
double result = 0.0;
while (x < end) {
result += step * func.apply(x);
x += step;
}
return result;
}
ForkJoinPool pool = new ForkJoinPool();
ForkJoinCalculate calc = new
ForkJoinCalculate(sqFunc, start, end, step);
double sum = pool.invoke(calc);
How to launch recursive execution
Spliterator
public class ForkJoinCalculate extends RecursiveTask<Double> {
...
static final long SEQUENTIAL_THRESHOLD = 500;
...
@Override
protected Double compute() {
if ((end - start) / step < SEQUENTIAL_THRESHOLD) {
return sequentialCompute();
}
double mid = start + (end - start) / 2.0;
ForkJoinCalculate left =
new ForkJoinCalculate(func, start, mid, step);
ForkJoinCalculate right =
new ForkJoinCalculate(func, mid, end, step);
left.fork();
double rightAns = right.compute();
double leftAns = left.join();
return leftAns + rightAns;
}
}
Collector
0
0,5
1
1,5
2
1 2 4 8 16 32
t(sec)
Threads
Execution time
Simple Threads
Thread Pool
Fork/Join
0
1
2
3
4
5
6
2 4 8 16 32
Speedup
Threads
Speedup
Simple Threads
Thread Pool
Fork/Join
Fork/Join effectiveness
• Local task queues and work stealing are only
utilized when worker threads actually schedule
new tasks in their own queues
– If this doesn't occur, the ForkJoinPool is just a
ThreadPoolExecutor with an extra overhead
– If input tasks are already split (or are splittable) into
tasks of approximately equal computing load, then it
less efficient than just using a ThreadPoolExecutor
directly
• If tasks have variable computing load and can be
split into subtasks, then ForkJoinPool's in-built
load balancing is likely to make it more efficient
than using a ThreadPoolExecutor
The F/J framework Criticism
• exceedingly complex
– The code looks more like an old C language program that was
segmented into classes than an O-O structure
• a design failure
– It’s primary uses are for fully-strict, compute-only, recursively
decomposing processing of large aggregate data structures. It is for
compute intensive tasks only
• lacking in industry professional attributes
– no monitoring, no alerting or logging, no availability for general
application usage
• misusing parallelization
– recursive decomposition has narrower performance window. An
academic exercise
• inadequate in scope
– you must be able to express things in terms of apply, reduce, filter,
map, cumulate, sort, uniquify, paired mappings, and so on — no
general purpose application programming here
• special purpose
F/J source code
F/J restrictions
• Recursive decomposition has narrower performance window. It
only works well:
– on balanced tree structures (DAG),
– where there are no cyclic dependencies,
– where the computation duration is neither too short nor too long,
– where there is no blocking
• Recommended restrictions:
– must be plain (between 100 and 10,000 basic computational steps in
the compute method),
– compute intensive code only,
– no blocking,
– no I/O,
– no synchronization
F/J restrictions
• Recursive decomposition has narrower performance window. It
only works well:
– on balanced tree structures (DAG),
– where there are no cyclic dependencies,
– where the computation duration is neither too short nor too long,
– where there is no blocking
• Recommended restrictions:
– must be plain (between 100 and 10,000 basic computational steps in
the compute method),
– compute intensive code only,
– no blocking,
– no I/O,
– no synchronization
All problems
F/J restrictions
• Recursive decomposition has narrower performance window. It
only works well:
– on balanced tree structures (DAG),
– where there are no cyclic dependencies,
– where the computation duration is neither too short nor too long,
– where there is no blocking
• Recommended restrictions:
– must be plain (between 100 and 10,000 basic computational steps in
the compute method),
– compute intensive code only,
– no blocking,
– no I/O,
– no synchronization F/J
All problems
reduce, filter, map, cumulate, sort,
uniquify, paired mappings, …
Lambda
1994
“He (Bill Joy) would often go on at length about
how great Oak would be if he could only add
closures and continuations and parameterized
types”
Patrick Naughton,
one of the creators of the Java
1994
“He (Bill Joy) would often go on at length about
how great Oak would be if he could only add
closures and continuations and parameterized
types”
“While we all agreed these were very cool language
features, we were all kind of hoping to finish this
language in our lifetimes and get on to creating cool
applications with it”
Patrick Naughton,
one of the creators of the Java
1994
“He (Bill Joy) would often go on at length about
how great Oak would be if he could only add
closures and continuations and parameterized
types”
“While we all agreed these were very cool language
features, we were all kind of hoping to finish this
language in our lifetimes and get on to creating cool
applications with it”
“It is also interesting that Bill was absolutely right
about what Java needs long term. When I go look
at the list of things he wanted to add back then, I
want them all. He was right, he usually is”
Patrick Naughton,
one of the creators of the Java
Ingredients of lambda expression
• A lambda expression has three ingredients:
– A block of code
– Parameters
– Values for the free variables; that is, the variables that
are not parameters and not defined inside the code
Ingredients of lambda expression
• A lambda expression has three ingredients:
– A block of code
– Parameters
– Values for the free variables; that is, the variables that
are not parameters and not defined inside the code
while (x < end) {
result += step * (sin(x) * sin(x) + cos(x) * cos(x));
x += step;
}
Ingredients of lambda expression
• A lambda expression has three ingredients:
– A block of code
– Parameters
– Values for the free variables; that is, the variables that
are not parameters and not defined inside the code
while (x < end) {
result += step * (sin(x) * sin(x) + cos(x) * cos(x));
x += step;
}
step * (sin(x) * sin(x) + cos(x) * cos(x));
Ingredients of lambda expression
• A lambda expression has three ingredients:
– A block of code
– Parameters
– Values for the free variables; that is, the variables that
are not parameters and not defined inside the code
while (x < end) {
result += step * (sin(x) * sin(x) + cos(x) * cos(x));
x += step;
}
step * (sin(x) * sin(x) + cos(x) * cos(x));
A block of code
Ingredients of lambda expression
• A lambda expression has three ingredients:
– A block of code
– Parameters
– Values for the free variables; that is, the variables that
are not parameters and not defined inside the code
while (x < end) {
result += step * (sin(x) * sin(x) + cos(x) * cos(x));
x += step;
}
step * (sin(x) * sin(x) + cos(x) * cos(x));
A block of code
Parameter(s)
Ingredients of lambda expression
• A lambda expression has three ingredients:
– A block of code
– Parameters
– Values for the free variables; that is, the variables that
are not parameters and not defined inside the code
while (x < end) {
result += step * (sin(x) * sin(x) + cos(x) * cos(x));
x += step;
}
step * (sin(x) * sin(x) + cos(x) * cos(x));
A block of code
Parameter(s)Free variable
Lambda expression
step * (sin(x) * sin(x) + cos(x) * cos(x));
Lambda expression
step * (sin(x) * sin(x) + cos(x) * cos(x));
x -> step * (sin(x) * sin(x) + cos(x) * cos(x));
Lambda expression
step * (sin(x) * sin(x) + cos(x) * cos(x));
x -> step * (sin(x) * sin(x) + cos(x) * cos(x));
Function<Double, Double> func =
x -> step * (sin(x) * sin(x) + cos(x) * cos(x));
Lambda expression
step * (sin(x) * sin(x) + cos(x) * cos(x));
x -> step * (sin(x) * sin(x) + cos(x) * cos(x));
Function<Double, Double> func =
x -> step * (sin(x) * sin(x) + cos(x) * cos(x));
F(x)G(y)
Lambda expression
step * (sin(x) * sin(x) + cos(x) * cos(x));
x -> step * (sin(x) * sin(x) + cos(x) * cos(x));
Function<Double, Double> func =
x -> step * (sin(x) * sin(x) + cos(x) * cos(x));
F(x)G(y)
Function<Double, Double> func =
x -> sin(x) * sin(x) + cos(x) * cos(x);
Function<Double, Double> calcFunc =
y -> step * y;
Function<Double, Double> sqFunc =
func.andThen(calcFunc);
SequentialCalculate sc = new SequentialCalculate (
new Function<Double, Double>() {
public Double apply(Double x) {
return sin(x) * sin(x) + cos(x) * cos(x);
}
}
);
SequentialCalculate sc = new SequentialCalculate (
new Function<Double, Double>() {
public Double apply(Double x) {
return sin(x) * sin(x) + cos(x) * cos(x);
}
}
);
SequentialCalculate sc =
new SequentialCalculate(x -> sin(x)*sin(x) + cos(x)*cos(x));
SequentialCalculate sc = new SequentialCalculate (
new Function<Double, Double>() {
public Double apply(Double x) {
return sin(x) * sin(x) + cos(x) * cos(x);
}
}
);
SequentialCalculate sc =
new SequentialCalculate(x -> sin(x)*sin(x) + cos(x)*cos(x));
Function<Double, Double> func =
x -> sin(x) * sin(x) + cos(x) * cos(x);
SequentialCalculate sc = new SequentialCalculate(func);
Stream API
Integral calculation
double step = 0.001;
double start = 0.0;
double end = 10_000.0;
Function<Double, Double> func =
x -> sin(x) * sin(x) + cos(x) * cos(x);
Function<Double, Double> calcFunc = y -> step * y;
Function<Double, Double> sqFunc = func.andThen(calcFunc);
double sum = ...
Integral calculation
double step = 0.001;
double start = 0.0;
double end = 10_000.0;
Function<Double, Double> func =
x -> sin(x) * sin(x) + cos(x) * cos(x);
Function<Double, Double> calcFunc = y -> step * y;
Function<Double, Double> sqFunc = func.andThen(calcFunc);
double sum = Stream.
iterate(0.0, s -> s + step).
Integral calculation
double step = 0.001;
double start = 0.0;
double end = 10_000.0;
Function<Double, Double> func =
x -> sin(x) * sin(x) + cos(x) * cos(x);
Function<Double, Double> calcFunc = y -> step * y;
Function<Double, Double> sqFunc = func.andThen(calcFunc);
double sum = Stream.
iterate(0.0, s -> s + step).
limit((long) ((end - start) / step)).
Integral calculation
double step = 0.001;
double start = 0.0;
double end = 10_000.0;
Function<Double, Double> func =
x -> sin(x) * sin(x) + cos(x) * cos(x);
Function<Double, Double> calcFunc = y -> step * y;
Function<Double, Double> sqFunc = func.andThen(calcFunc);
double sum = Stream.
iterate(0.0, s -> s + step).
limit((long) ((end - start) / step)).
map(sqFunc).
Integral calculation
double step = 0.001;
double start = 0.0;
double end = 10_000.0;
Function<Double, Double> func =
x -> sin(x) * sin(x) + cos(x) * cos(x);
Function<Double, Double> calcFunc = y -> step * y;
Function<Double, Double> sqFunc = func.andThen(calcFunc);
double sum = Stream.
iterate(0.0, s -> s + step).
limit((long) ((end - start) / step)).
map(sqFunc).
reduce(0.0, Double::sum); ∑ sum
java.util.function.*
public interface Function<T, R> {
R apply(T t);
}
public interface DoubleUnaryOperator {
double applyAsDouble(double x);
}
DoubleStream
public interface DoubleUnaryOperator {
double applyAsDouble(double x);
}
DoubleStream
DoubleUnaryOperator funcD =
x -> sin(x) * sin(x) + cos(x) * cos(x);
DoubleUnaryOperator calcFuncD = y -> step * y;
DoubleUnaryOperator sqFuncDouble = funcD.andThen(calcFuncD);
double sum = ...
public interface DoubleUnaryOperator {
double applyAsDouble(double x);
}
DoubleStream
DoubleUnaryOperator funcD =
x -> sin(x) * sin(x) + cos(x) * cos(x);
DoubleUnaryOperator calcFuncD = y -> step * y;
DoubleUnaryOperator sqFuncDouble = funcD.andThen(calcFuncD);
double sum = DoubleStream.
iterate(0.0, s -> s + step).
limit((long) ((end - start) / step)).
map(sqFuncDouble).
sum();
public interface DoubleUnaryOperator {
double applyAsDouble(double x);
}
What's the difference?
1,7
1,75
1,8
1,85
1,9
1,95
2
2,05
2,1
2,15
2,2
Execution time
Sequential
Generic Stream
Double Stream
Stream parallel
double sum = DoubleStream.
iterate(0.0, s -> s + step).
limit((long) ((end - start) / step)).
parallel().
map(sqFuncDouble).
sum();
Stream parallel
double sum = DoubleStream.
iterate(0.0, s -> s + step).
limit((long) ((end - start) / step)).
parallel().
map(sqFuncDouble).
sum();
and …
and …
and …
http://mail.openjdk.java.net/pipermail/lambda-dev/2013-June/010019.html
Stream parallel v.2
double sum = LongStream.
range(0, (long) ((end - start) / step)).
parallel().
mapToDouble(i -> start + step * i).
map(sqFuncDouble).
sum();
Stream parallel v.2
double sum = LongStream.
range(0, (long) ((end - start) / step)).
parallel().
mapToDouble(i -> start + step * i).
map(sqFuncDouble).
sum();
Spliterator
Collector
Streams parallel v.2
double sum = LongStream.
range(0, (long) ((end - start) / step)).
parallel().
mapToDouble(i -> start + step * i).
map(sqFuncDouble).
sum();
0,35
0,355
0,36
0,365
0,37
0,375
0,38
0,385
0,39
Execution time
Simple Threads Thread Pool
Fork/Join Double Stream Parallel
http://stackoverflow.com/questions/20375176/should-i-always-use-a-parallel-stream-when-possible?rq=1
Parallel stream problem
https://bugs.openjdk.java.net/browse/JDK-8032512
• The problem is that all parallel streams use common fork-join
thread pool and if you submit a long-running task, you effectively
block all threads in the pool.
• By default, all streams will use the same ForkJoinPool, configured to
use as many threads as there are cores in the computer on which
the program is running.
• So, for computation intensive stream evaluation, one should always
use a specific ForkJoinPool in order not to block other streams.
0
0,5
1
1,5
2
2,5
Execution time
Sequential
Generic Stream
Double Stream
Simple Threads
Thread Pool
Fork/Join
Double Stream Parallel
Thank you!
javaday.org.ua

More Related Content

What's hot

What's hot (20)

Network simulator 2
Network simulator 2Network simulator 2
Network simulator 2
 
Comparing JVM languages
Comparing JVM languagesComparing JVM languages
Comparing JVM languages
 
Thread
ThreadThread
Thread
 
Hw09 Hadoop + Clojure
Hw09   Hadoop + ClojureHw09   Hadoop + Clojure
Hw09 Hadoop + Clojure
 
Go concurrency
Go concurrencyGo concurrency
Go concurrency
 
Kotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime PerformanceKotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime Performance
 
Python Async IO Horizon
Python Async IO HorizonPython Async IO Horizon
Python Async IO Horizon
 
Venkat ns2
Venkat ns2Venkat ns2
Venkat ns2
 
Go Concurrency Basics
Go Concurrency Basics Go Concurrency Basics
Go Concurrency Basics
 
Ns 2 Network Simulator An Introduction
Ns 2 Network Simulator An IntroductionNs 2 Network Simulator An Introduction
Ns 2 Network Simulator An Introduction
 
Hadoop + Clojure
Hadoop + ClojureHadoop + Clojure
Hadoop + Clojure
 
Refactor case study LAN example
Refactor case study LAN exampleRefactor case study LAN example
Refactor case study LAN example
 
Kirk Shoop, Reactive programming in C++
Kirk Shoop, Reactive programming in C++Kirk Shoop, Reactive programming in C++
Kirk Shoop, Reactive programming in C++
 
Python Asíncrono - Async Python
Python Asíncrono - Async PythonPython Asíncrono - Async Python
Python Asíncrono - Async Python
 
Java file
Java fileJava file
Java file
 
The future of async i/o in Python
The future of async i/o in PythonThe future of async i/o in Python
The future of async i/o in Python
 
Concurrency in Golang
Concurrency in GolangConcurrency in Golang
Concurrency in Golang
 
Go Concurrency
Go ConcurrencyGo Concurrency
Go Concurrency
 
Multithreading done right
Multithreading done rightMultithreading done right
Multithreading done right
 
TechTalk - Dotnet
TechTalk - DotnetTechTalk - Dotnet
TechTalk - Dotnet
 

Similar to От Java Threads к лямбдам, Андрей Родионов

Presto anatomy
Presto anatomyPresto anatomy
Presto anatomyDongmin Yu
 
MapReduce wordcount program
MapReduce wordcount program MapReduce wordcount program
MapReduce wordcount program Sarwan Singh
 
History of asynchronous in .NET
History of asynchronous in .NETHistory of asynchronous in .NET
History of asynchronous in .NETMarcin Tyborowski
 
NVIDIA HPC ソフトウエア斜め読み
NVIDIA HPC ソフトウエア斜め読みNVIDIA HPC ソフトウエア斜め読み
NVIDIA HPC ソフトウエア斜め読みNVIDIA Japan
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScriptQiangning Hong
 
GDG Devfest 2019 - Build go kit microservices at kubernetes with ease
GDG Devfest 2019 - Build go kit microservices at kubernetes with easeGDG Devfest 2019 - Build go kit microservices at kubernetes with ease
GDG Devfest 2019 - Build go kit microservices at kubernetes with easeKAI CHU CHUNG
 
[245] presto 내부구조 파헤치기
[245] presto 내부구조 파헤치기[245] presto 내부구조 파헤치기
[245] presto 내부구조 파헤치기NAVER D2
 
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...GeeksLab Odessa
 
Job Queue in Golang
Job Queue in GolangJob Queue in Golang
Job Queue in GolangBo-Yi Wu
 
Server side JavaScript: going all the way
Server side JavaScript: going all the wayServer side JavaScript: going all the way
Server side JavaScript: going all the wayOleg Podsechin
 
CSharp for Unity Day2
CSharp for Unity Day2CSharp for Unity Day2
CSharp for Unity Day2Duong Thanh
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)Pavlo Baron
 
How to Leverage Go for Your Networking Needs
How to Leverage Go for Your Networking NeedsHow to Leverage Go for Your Networking Needs
How to Leverage Go for Your Networking NeedsDigitalOcean
 
Parallel and Async Programming With C#
Parallel and Async Programming With C#Parallel and Async Programming With C#
Parallel and Async Programming With C#Rainer Stropek
 
Reactive programming every day
Reactive programming every dayReactive programming every day
Reactive programming every dayVadym Khondar
 
Emerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the HorizonEmerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the HorizonAlex Payne
 
Unit Testing Express and Koa Middleware in ES2015
Unit Testing Express and Koa Middleware in ES2015Unit Testing Express and Koa Middleware in ES2015
Unit Testing Express and Koa Middleware in ES2015Morris Singer
 

Similar to От Java Threads к лямбдам, Андрей Родионов (20)

Presto anatomy
Presto anatomyPresto anatomy
Presto anatomy
 
MapReduce wordcount program
MapReduce wordcount program MapReduce wordcount program
MapReduce wordcount program
 
History of asynchronous in .NET
History of asynchronous in .NETHistory of asynchronous in .NET
History of asynchronous in .NET
 
NVIDIA HPC ソフトウエア斜め読み
NVIDIA HPC ソフトウエア斜め読みNVIDIA HPC ソフトウエア斜め読み
NVIDIA HPC ソフトウエア斜め読み
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript
 
GDG Devfest 2019 - Build go kit microservices at kubernetes with ease
GDG Devfest 2019 - Build go kit microservices at kubernetes with easeGDG Devfest 2019 - Build go kit microservices at kubernetes with ease
GDG Devfest 2019 - Build go kit microservices at kubernetes with ease
 
[245] presto 내부구조 파헤치기
[245] presto 내부구조 파헤치기[245] presto 내부구조 파헤치기
[245] presto 내부구조 파헤치기
 
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
 
Job Queue in Golang
Job Queue in GolangJob Queue in Golang
Job Queue in Golang
 
Next .NET and C#
Next .NET and C#Next .NET and C#
Next .NET and C#
 
Server side JavaScript: going all the way
Server side JavaScript: going all the wayServer side JavaScript: going all the way
Server side JavaScript: going all the way
 
CSharp for Unity Day2
CSharp for Unity Day2CSharp for Unity Day2
CSharp for Unity Day2
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)
 
Hadoop ecosystem
Hadoop ecosystemHadoop ecosystem
Hadoop ecosystem
 
Hadoop ecosystem
Hadoop ecosystemHadoop ecosystem
Hadoop ecosystem
 
How to Leverage Go for Your Networking Needs
How to Leverage Go for Your Networking NeedsHow to Leverage Go for Your Networking Needs
How to Leverage Go for Your Networking Needs
 
Parallel and Async Programming With C#
Parallel and Async Programming With C#Parallel and Async Programming With C#
Parallel and Async Programming With C#
 
Reactive programming every day
Reactive programming every dayReactive programming every day
Reactive programming every day
 
Emerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the HorizonEmerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the Horizon
 
Unit Testing Express and Koa Middleware in ES2015
Unit Testing Express and Koa Middleware in ES2015Unit Testing Express and Koa Middleware in ES2015
Unit Testing Express and Koa Middleware in ES2015
 

More from Yandex

Предсказание оттока игроков из World of Tanks
Предсказание оттока игроков из World of TanksПредсказание оттока игроков из World of Tanks
Предсказание оттока игроков из World of TanksYandex
 
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...Yandex
 
Структурированные данные, Юлия Тихоход, лекция в Школе вебмастеров Яндекса
Структурированные данные, Юлия Тихоход, лекция в Школе вебмастеров ЯндексаСтруктурированные данные, Юлия Тихоход, лекция в Школе вебмастеров Яндекса
Структурированные данные, Юлия Тихоход, лекция в Школе вебмастеров ЯндексаYandex
 
Представление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров Яндекса
Представление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров ЯндексаПредставление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров Яндекса
Представление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров ЯндексаYandex
 
Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...
Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...
Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...Yandex
 
Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...
Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...
Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...Yandex
 
Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...
Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...
Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...Yandex
 
Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...
Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...
Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...Yandex
 
Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...
Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...
Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...Yandex
 
Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...
Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...
Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...Yandex
 
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...Yandex
 
Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...
Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...
Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...Yandex
 
Как защитить свой сайт, Пётр Волков, лекция в Школе вебмастеров
Как защитить свой сайт, Пётр Волков, лекция в Школе вебмастеровКак защитить свой сайт, Пётр Волков, лекция в Школе вебмастеров
Как защитить свой сайт, Пётр Волков, лекция в Школе вебмастеровYandex
 
Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...
Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...
Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...Yandex
 
Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...
Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...
Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...Yandex
 
Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...
Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...
Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...Yandex
 
Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...
Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...
Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...Yandex
 
Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...
Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...
Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...Yandex
 
Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...
Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...
Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...Yandex
 
Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...
Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...
Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...Yandex
 

More from Yandex (20)

Предсказание оттока игроков из World of Tanks
Предсказание оттока игроков из World of TanksПредсказание оттока игроков из World of Tanks
Предсказание оттока игроков из World of Tanks
 
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...
 
Структурированные данные, Юлия Тихоход, лекция в Школе вебмастеров Яндекса
Структурированные данные, Юлия Тихоход, лекция в Школе вебмастеров ЯндексаСтруктурированные данные, Юлия Тихоход, лекция в Школе вебмастеров Яндекса
Структурированные данные, Юлия Тихоход, лекция в Школе вебмастеров Яндекса
 
Представление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров Яндекса
Представление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров ЯндексаПредставление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров Яндекса
Представление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров Яндекса
 
Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...
Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...
Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...
 
Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...
Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...
Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...
 
Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...
Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...
Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...
 
Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...
Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...
Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...
 
Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...
Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...
Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...
 
Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...
Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...
Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...
 
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
 
Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...
Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...
Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...
 
Как защитить свой сайт, Пётр Волков, лекция в Школе вебмастеров
Как защитить свой сайт, Пётр Волков, лекция в Школе вебмастеровКак защитить свой сайт, Пётр Волков, лекция в Школе вебмастеров
Как защитить свой сайт, Пётр Волков, лекция в Школе вебмастеров
 
Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...
Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...
Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...
 
Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...
Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...
Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...
 
Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...
Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...
Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...
 
Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...
Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...
Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...
 
Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...
Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...
Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...
 
Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...
Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...
Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...
 
Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...
Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...
Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...
 

Recently uploaded

SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 

Recently uploaded (20)

SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping Elbows
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 

От Java Threads к лямбдам, Андрей Родионов

  • 1. От Java Threads к лямбдам Андрей Родионов @AndriiRodionov http://jug.ua/
  • 3. The Star7 PDA • SPARC based, handheld wireless PDA • with a 5" color LCD with touchscreen input • a new 16 bit color hardware double buffered NTSC framebuffer • 900MHz wireless networking • multi-media audio codec • a new power supply/battery interface • a version of Unix (SolarisOs) that runs in under a megabyte including drivers for PCMCIA • radio networking • flash RAM file system
  • 4. + Оак • a new small, safe, secure, distributed, robust, interpreted, garbage collected, multi-threaded, architecture neutral, high performance, dynamic programming language • a set of classes that implement a spatial user interface metaphor, a user interface methodology which uses animation, audio, spatial cues, gestures • All of this, in 1992!
  • 5. Зачем это все? • Если Oak предназначался для подобных устройств, когда еще было не особо много многопроцессорных машин (и тем более никто не мечтала о телефоне с 4 ядрами), то зачем он изначально содержал поддержку потоков???
  • 6.
  • 7. Напишем реализации одной и той же задачи с использованием • Sequential algorithm • Java Threads • java.util.concurrent (Thread pool) • Fork/Join • Java 8 Stream API (Lambda)
  • 8. А так же … • Сравним производительность каждого из подходов
  • 10. Вы занимаетесь микробенчмаркингом? Тогда мы идем к Вам! (The Art Of) (Java) Benchmarking http://shipilev.net/
  • 11. http://openjdk.java.net/projects/code-tools/jmh/ JMH is a Java harness for building, running, and analysing nano/micro/milli/macro benchmarks written in Java and other languages targetting the JVM.
  • 12. В качестве задачи – численное интегрирование • Методом прямоугольников
  • 14. Sequential v.1 public class SequentialCalculate { public double calculate(double start, double end, double step) { double result = 0.0; double x = start; while (x < end) { result += step * (sin(x) * sin(x) + cos(x) * cos(x)); x += step; } return result; } }
  • 15. Sequential v.1 public class SequentialCalculate { public double calculate(double start, double end, double step) { double result = 0.0; double x = start; while (x < end) { result += step * (sin(x) * sin(x) + cos(x) * cos(x)); x += step; } return result; } }
  • 16. Sequential v.2: with Functional interface public interface Function<T, R> { R apply(T t); }
  • 17. Sequential v.2: with Functional interface public interface Function<T, R> { R apply(T t); } public class SequentialCalculate { private final Function<Double, Double> func; public SequentialCalculate(Function<Double, Double> func) { this.func = func; } public double calculate(double start, double end, double step) { double result = 0.0; double x = start; while (x < end) { result += step * func.apply(x); x += step; } return result; } }
  • 18. Sequential v.2 With Functional interface SequentialCalculate sc = new SequentialCalculate ( new Function<Double, Double>() { public Double apply(Double x) { return sin(x) * sin(x) + cos(x) * cos(x); } } );
  • 19. Performance • Intel Core i7-4770, 3.4GHz, 4 Physical cores + 4 Hyper threading = 8 CPUs • Sun UltraSPARC T1, 1.0GHz, 8 Physical cores * 4 Light Weight Processes = 32 CPUs 54,832 1,877 0 10 20 30 40 50 60 t, sec
  • 22. class CalcThread extends Thread { private final double start; private final double end; private final double step; private double partialResult; public CalcThread(double start, double end, double step) { this.start = start; this.end = end; this.step = step; } public void run() { double x = start; while (x < end) { partialResult += step * func.apply(x); x += step; } } }
  • 23. public double calculate(double start, double end, double step, int chunks) { CalcThread[] calcThreads = new CalcThread[chunks]; double interval = (end - start) / chunks; double st = start; for (int i = 0; i < chunks; i++) { calcThreads[i] = new CalcThread(st, st + interval, step); calcThreads[i].start(); st += interval; } double result = 0.0; for (CalcThread cs : calcThreads) { cs.join(); result += cs.partialResult; } return result; }
  • 24. Spliterator Collector public double calculate(double start, double end, double step, int chunks) { CalcThread[] calcThreads = new CalcThread[chunks]; double interval = (end - start) / chunks; double st = start; for (int i = 0; i < chunks; i++) { calcThreads[i] = new CalcThread(st, st + interval, step); calcThreads[i].start(); st += interval; } double result = 0.0; for (CalcThread cs : calcThreads) { cs.join(); result += cs.partialResult; } return result; }
  • 25. 0 0,5 1 1,5 2 1 2 4 8 16 32 t(sec) Threads Execution time Simple Threads
  • 26. 0 1 2 3 4 5 6 2 4 8 16 32 Speedup Threads Speedup Simple Threads
  • 27. Ограничения классического подхода • "поток-на-задачу" хорошо работает с небольшим количеством долгосрочных задач • слияние низкоуровневого кода, отвечающего за многопоточное исполнение, и высокоуровневого кода, отвечающего за основную функциональность приложения приводит к т.н. «спагетти-коду» • трудности связанные с управлением потоками • поток занимает относительно много места в памяти ~ 1 Mb • для выполнения новой задачи потребуется запустить новый поток – это одна из самых требовательных к ресурсам операций
  • 29. Thread pool • Пул потоков - это очередь в сочетании с фиксированной группой рабочих потоков, в которой используются wait() и notify(), чтобы сигнализировать ожидающим потокам, что прибыла новая работа.
  • 30. class CalcThread implements Callable<Double> { private final double start; private final double end; private final double step; public CalcThread(double start, double end, double step){ this.start = start; this.end = end; this.step = step; } public Double call() { double partialResult = 0.0; double x = start; while (x < end) { partialResult += step * func.apply(x); x += step; } return partialResult; } }
  • 31. public double calculate(double start, double end, double step, int chunks) { ExecutorService executorService = Executors.newFixedThreadPool(chunks); Future<Double>[] futures = new Future[chunks]; double interval = (end - start) / chunks; double st = start; for (int i = 0; i < chunks; i++) { futures[i] = executorService.submit( new CalcThread(st, st + interval, step)); st += interval; } executorService.shutdown(); double result = 0.0; for (Future<Double> partRes : futures) { result += partRes.get(); } return result; }
  • 32. public double calculate(double start, double end, double step, int chunks) { ExecutorService executorService = Executors.newFixedThreadPool(chunks); Future<Double>[] futures = new Future[chunks]; double interval = (end - start) / chunks; double st = start; for (int i = 0; i < chunks; i++) { futures[i] = executorService.submit( new CalcThread(st, st + interval, step)); st += interval; } executorService.shutdown(); double result = 0.0; for (Future<Double> partRes : futures) { result += partRes.get(); } return result; } Spliterator Collector
  • 33. 0 0,5 1 1,5 2 1 2 4 8 16 32 t(sec) Threads Execution time Simple Threads Thread Pool
  • 34. 0 1 2 3 4 5 6 2 4 8 16 32 Speedup Threads Speedup Simple Threads Thread Pool
  • 35. «Бытие определяет сознание» Доминирующие в текущий момент аппаратные платформы формируют подход к созданию языков, библиотек и систем • С самого момента зарождения языка в Java была поддержка потоков и параллелизма (Thread, synchronized, volatile, …) • Однако примитивы параллелизма, введенные в 1995 году, отражали реальность аппаратного обеспечения того времени: большинство доступных коммерческих систем вообще не предоставляли возможностей использования параллелизма, и даже наиболее дорогостоящие системы предоставляли такие возможности лишь в ограниченных масштабах • В те дни потоки использовались в основном, для выражения asynchrony, а не concurrency, и в результате, эти механизмы в целом отвечали требованиям времени
  • 36. Путь к параллелизму • По мере изменения доминирующей аппаратной платформы, должна соответственно изменяться и программная платформа • Когда начался процесс удешевления многопроцессорных систем, от приложений стали требовать все большего использования предоставляемого системами аппаратного параллелизма. Тогда программисты обнаружили, что разрабатывать параллельные программы, использующие низкоуровневые примитивы, обеспечиваемые языком и библиотекой классов, сложно и чревато ошибками • java.util.concurrent дала возможности для «coarse-grained» параллелизма (поток на запрос), но этого может быть не достаточно, т.к. сам по себе запрос может выполняться долго • Необходимы средства для «finer-grained» параллелизма Web server Th1 Th2 Th3 ThNcoarse-grained parallelism finer-grained parallelism
  • 38. Fork/Join // PSEUDOCODE Result solve(Problem problem) { if (problem.size < SEQUENTIAL_THRESHOLD) return solveSequentially(problem); else { Result left, right; INVOKE-IN-PARALLEL { left = solve(extractLeftHalf(problem)); right = solve(extractRightHalf(problem)); } return combine(left, right); } } • Fork/Join сейчас является одной из самых распространённых методик для построения параллельных алгоритмов
  • 39. Work stealing - планировщики на основе захвата работы ForkJoinPool может в небольшом количестве потоков выполнить существенно большее число задач
  • 40. Work stealing • Планировщики на основе захвата работы (work stealing) "автоматически" балансируют нагрузку за счёт того, что потоки, оказавшиеся без задач, самостоятельно обнаруживают и забирают "свободные" задачи у других потоков. Находится ли поток-"жертва" в активном или пассивном состоянии, неважно. • Основными преимуществами перед планировщиком с общим пулом задач: – отсутствие общего пула :), то есть точки глобальной синхронизации – лучшая локальность данных, потому что в большинстве случаев поток самостоятельно выполняет порождённые им задачи
  • 41. public class ForkJoinCalculate extends RecursiveTask<Double> { ... static final long SEQUENTIAL_THRESHOLD = 500; ... @Override protected Double compute() { if ((end - start) / step < SEQUENTIAL_THRESHOLD) { return sequentialCompute(); } double mid = start + (end - start) / 2.0; ForkJoinCalculate left = new ForkJoinCalculate(func, start, mid, step); ForkJoinCalculate right = new ForkJoinCalculate(func, mid, end, step); left.fork(); double rightAns = right.compute(); double leftAns = left.join(); return leftAns + rightAns; } }
  • 42. protected double sequentialCompute() { double x = start; double result = 0.0; while (x < end) { result += step * func.apply(x); x += step; } return result; }
  • 43. ForkJoinPool pool = new ForkJoinPool(); ForkJoinCalculate calc = new ForkJoinCalculate(sqFunc, start, end, step); double sum = pool.invoke(calc); How to launch recursive execution
  • 44. Spliterator public class ForkJoinCalculate extends RecursiveTask<Double> { ... static final long SEQUENTIAL_THRESHOLD = 500; ... @Override protected Double compute() { if ((end - start) / step < SEQUENTIAL_THRESHOLD) { return sequentialCompute(); } double mid = start + (end - start) / 2.0; ForkJoinCalculate left = new ForkJoinCalculate(func, start, mid, step); ForkJoinCalculate right = new ForkJoinCalculate(func, mid, end, step); left.fork(); double rightAns = right.compute(); double leftAns = left.join(); return leftAns + rightAns; } } Collector
  • 45. 0 0,5 1 1,5 2 1 2 4 8 16 32 t(sec) Threads Execution time Simple Threads Thread Pool Fork/Join
  • 46. 0 1 2 3 4 5 6 2 4 8 16 32 Speedup Threads Speedup Simple Threads Thread Pool Fork/Join
  • 47. Fork/Join effectiveness • Local task queues and work stealing are only utilized when worker threads actually schedule new tasks in their own queues – If this doesn't occur, the ForkJoinPool is just a ThreadPoolExecutor with an extra overhead – If input tasks are already split (or are splittable) into tasks of approximately equal computing load, then it less efficient than just using a ThreadPoolExecutor directly • If tasks have variable computing load and can be split into subtasks, then ForkJoinPool's in-built load balancing is likely to make it more efficient than using a ThreadPoolExecutor
  • 48. The F/J framework Criticism • exceedingly complex – The code looks more like an old C language program that was segmented into classes than an O-O structure • a design failure – It’s primary uses are for fully-strict, compute-only, recursively decomposing processing of large aggregate data structures. It is for compute intensive tasks only • lacking in industry professional attributes – no monitoring, no alerting or logging, no availability for general application usage • misusing parallelization – recursive decomposition has narrower performance window. An academic exercise • inadequate in scope – you must be able to express things in terms of apply, reduce, filter, map, cumulate, sort, uniquify, paired mappings, and so on — no general purpose application programming here • special purpose
  • 50. F/J restrictions • Recursive decomposition has narrower performance window. It only works well: – on balanced tree structures (DAG), – where there are no cyclic dependencies, – where the computation duration is neither too short nor too long, – where there is no blocking • Recommended restrictions: – must be plain (between 100 and 10,000 basic computational steps in the compute method), – compute intensive code only, – no blocking, – no I/O, – no synchronization
  • 51. F/J restrictions • Recursive decomposition has narrower performance window. It only works well: – on balanced tree structures (DAG), – where there are no cyclic dependencies, – where the computation duration is neither too short nor too long, – where there is no blocking • Recommended restrictions: – must be plain (between 100 and 10,000 basic computational steps in the compute method), – compute intensive code only, – no blocking, – no I/O, – no synchronization All problems
  • 52. F/J restrictions • Recursive decomposition has narrower performance window. It only works well: – on balanced tree structures (DAG), – where there are no cyclic dependencies, – where the computation duration is neither too short nor too long, – where there is no blocking • Recommended restrictions: – must be plain (between 100 and 10,000 basic computational steps in the compute method), – compute intensive code only, – no blocking, – no I/O, – no synchronization F/J All problems reduce, filter, map, cumulate, sort, uniquify, paired mappings, …
  • 54.
  • 55. 1994 “He (Bill Joy) would often go on at length about how great Oak would be if he could only add closures and continuations and parameterized types” Patrick Naughton, one of the creators of the Java
  • 56. 1994 “He (Bill Joy) would often go on at length about how great Oak would be if he could only add closures and continuations and parameterized types” “While we all agreed these were very cool language features, we were all kind of hoping to finish this language in our lifetimes and get on to creating cool applications with it” Patrick Naughton, one of the creators of the Java
  • 57. 1994 “He (Bill Joy) would often go on at length about how great Oak would be if he could only add closures and continuations and parameterized types” “While we all agreed these were very cool language features, we were all kind of hoping to finish this language in our lifetimes and get on to creating cool applications with it” “It is also interesting that Bill was absolutely right about what Java needs long term. When I go look at the list of things he wanted to add back then, I want them all. He was right, he usually is” Patrick Naughton, one of the creators of the Java
  • 58. Ingredients of lambda expression • A lambda expression has three ingredients: – A block of code – Parameters – Values for the free variables; that is, the variables that are not parameters and not defined inside the code
  • 59. Ingredients of lambda expression • A lambda expression has three ingredients: – A block of code – Parameters – Values for the free variables; that is, the variables that are not parameters and not defined inside the code while (x < end) { result += step * (sin(x) * sin(x) + cos(x) * cos(x)); x += step; }
  • 60. Ingredients of lambda expression • A lambda expression has three ingredients: – A block of code – Parameters – Values for the free variables; that is, the variables that are not parameters and not defined inside the code while (x < end) { result += step * (sin(x) * sin(x) + cos(x) * cos(x)); x += step; } step * (sin(x) * sin(x) + cos(x) * cos(x));
  • 61. Ingredients of lambda expression • A lambda expression has three ingredients: – A block of code – Parameters – Values for the free variables; that is, the variables that are not parameters and not defined inside the code while (x < end) { result += step * (sin(x) * sin(x) + cos(x) * cos(x)); x += step; } step * (sin(x) * sin(x) + cos(x) * cos(x)); A block of code
  • 62. Ingredients of lambda expression • A lambda expression has three ingredients: – A block of code – Parameters – Values for the free variables; that is, the variables that are not parameters and not defined inside the code while (x < end) { result += step * (sin(x) * sin(x) + cos(x) * cos(x)); x += step; } step * (sin(x) * sin(x) + cos(x) * cos(x)); A block of code Parameter(s)
  • 63. Ingredients of lambda expression • A lambda expression has three ingredients: – A block of code – Parameters – Values for the free variables; that is, the variables that are not parameters and not defined inside the code while (x < end) { result += step * (sin(x) * sin(x) + cos(x) * cos(x)); x += step; } step * (sin(x) * sin(x) + cos(x) * cos(x)); A block of code Parameter(s)Free variable
  • 64. Lambda expression step * (sin(x) * sin(x) + cos(x) * cos(x));
  • 65. Lambda expression step * (sin(x) * sin(x) + cos(x) * cos(x)); x -> step * (sin(x) * sin(x) + cos(x) * cos(x));
  • 66. Lambda expression step * (sin(x) * sin(x) + cos(x) * cos(x)); x -> step * (sin(x) * sin(x) + cos(x) * cos(x)); Function<Double, Double> func = x -> step * (sin(x) * sin(x) + cos(x) * cos(x));
  • 67. Lambda expression step * (sin(x) * sin(x) + cos(x) * cos(x)); x -> step * (sin(x) * sin(x) + cos(x) * cos(x)); Function<Double, Double> func = x -> step * (sin(x) * sin(x) + cos(x) * cos(x)); F(x)G(y)
  • 68. Lambda expression step * (sin(x) * sin(x) + cos(x) * cos(x)); x -> step * (sin(x) * sin(x) + cos(x) * cos(x)); Function<Double, Double> func = x -> step * (sin(x) * sin(x) + cos(x) * cos(x)); F(x)G(y) Function<Double, Double> func = x -> sin(x) * sin(x) + cos(x) * cos(x); Function<Double, Double> calcFunc = y -> step * y; Function<Double, Double> sqFunc = func.andThen(calcFunc);
  • 69. SequentialCalculate sc = new SequentialCalculate ( new Function<Double, Double>() { public Double apply(Double x) { return sin(x) * sin(x) + cos(x) * cos(x); } } );
  • 70. SequentialCalculate sc = new SequentialCalculate ( new Function<Double, Double>() { public Double apply(Double x) { return sin(x) * sin(x) + cos(x) * cos(x); } } ); SequentialCalculate sc = new SequentialCalculate(x -> sin(x)*sin(x) + cos(x)*cos(x));
  • 71. SequentialCalculate sc = new SequentialCalculate ( new Function<Double, Double>() { public Double apply(Double x) { return sin(x) * sin(x) + cos(x) * cos(x); } } ); SequentialCalculate sc = new SequentialCalculate(x -> sin(x)*sin(x) + cos(x)*cos(x)); Function<Double, Double> func = x -> sin(x) * sin(x) + cos(x) * cos(x); SequentialCalculate sc = new SequentialCalculate(func);
  • 73. Integral calculation double step = 0.001; double start = 0.0; double end = 10_000.0; Function<Double, Double> func = x -> sin(x) * sin(x) + cos(x) * cos(x); Function<Double, Double> calcFunc = y -> step * y; Function<Double, Double> sqFunc = func.andThen(calcFunc); double sum = ...
  • 74. Integral calculation double step = 0.001; double start = 0.0; double end = 10_000.0; Function<Double, Double> func = x -> sin(x) * sin(x) + cos(x) * cos(x); Function<Double, Double> calcFunc = y -> step * y; Function<Double, Double> sqFunc = func.andThen(calcFunc); double sum = Stream. iterate(0.0, s -> s + step).
  • 75. Integral calculation double step = 0.001; double start = 0.0; double end = 10_000.0; Function<Double, Double> func = x -> sin(x) * sin(x) + cos(x) * cos(x); Function<Double, Double> calcFunc = y -> step * y; Function<Double, Double> sqFunc = func.andThen(calcFunc); double sum = Stream. iterate(0.0, s -> s + step). limit((long) ((end - start) / step)).
  • 76. Integral calculation double step = 0.001; double start = 0.0; double end = 10_000.0; Function<Double, Double> func = x -> sin(x) * sin(x) + cos(x) * cos(x); Function<Double, Double> calcFunc = y -> step * y; Function<Double, Double> sqFunc = func.andThen(calcFunc); double sum = Stream. iterate(0.0, s -> s + step). limit((long) ((end - start) / step)). map(sqFunc).
  • 77. Integral calculation double step = 0.001; double start = 0.0; double end = 10_000.0; Function<Double, Double> func = x -> sin(x) * sin(x) + cos(x) * cos(x); Function<Double, Double> calcFunc = y -> step * y; Function<Double, Double> sqFunc = func.andThen(calcFunc); double sum = Stream. iterate(0.0, s -> s + step). limit((long) ((end - start) / step)). map(sqFunc). reduce(0.0, Double::sum); ∑ sum
  • 78. java.util.function.* public interface Function<T, R> { R apply(T t); } public interface DoubleUnaryOperator { double applyAsDouble(double x); }
  • 79. DoubleStream public interface DoubleUnaryOperator { double applyAsDouble(double x); }
  • 80. DoubleStream DoubleUnaryOperator funcD = x -> sin(x) * sin(x) + cos(x) * cos(x); DoubleUnaryOperator calcFuncD = y -> step * y; DoubleUnaryOperator sqFuncDouble = funcD.andThen(calcFuncD); double sum = ... public interface DoubleUnaryOperator { double applyAsDouble(double x); }
  • 81. DoubleStream DoubleUnaryOperator funcD = x -> sin(x) * sin(x) + cos(x) * cos(x); DoubleUnaryOperator calcFuncD = y -> step * y; DoubleUnaryOperator sqFuncDouble = funcD.andThen(calcFuncD); double sum = DoubleStream. iterate(0.0, s -> s + step). limit((long) ((end - start) / step)). map(sqFuncDouble). sum(); public interface DoubleUnaryOperator { double applyAsDouble(double x); }
  • 83. Stream parallel double sum = DoubleStream. iterate(0.0, s -> s + step). limit((long) ((end - start) / step)). parallel(). map(sqFuncDouble). sum();
  • 84.
  • 85.
  • 86.
  • 87. Stream parallel double sum = DoubleStream. iterate(0.0, s -> s + step). limit((long) ((end - start) / step)). parallel(). map(sqFuncDouble). sum();
  • 91.
  • 92. Stream parallel v.2 double sum = LongStream. range(0, (long) ((end - start) / step)). parallel(). mapToDouble(i -> start + step * i). map(sqFuncDouble). sum();
  • 93. Stream parallel v.2 double sum = LongStream. range(0, (long) ((end - start) / step)). parallel(). mapToDouble(i -> start + step * i). map(sqFuncDouble). sum();
  • 94. Spliterator Collector Streams parallel v.2 double sum = LongStream. range(0, (long) ((end - start) / step)). parallel(). mapToDouble(i -> start + step * i). map(sqFuncDouble). sum();
  • 97. Parallel stream problem https://bugs.openjdk.java.net/browse/JDK-8032512 • The problem is that all parallel streams use common fork-join thread pool and if you submit a long-running task, you effectively block all threads in the pool. • By default, all streams will use the same ForkJoinPool, configured to use as many threads as there are cores in the computer on which the program is running. • So, for computation intensive stream evaluation, one should always use a specific ForkJoinPool in order not to block other streams.
  • 98. 0 0,5 1 1,5 2 2,5 Execution time Sequential Generic Stream Double Stream Simple Threads Thread Pool Fork/Join Double Stream Parallel