자바의 병렬 처리 발전사
2019. 5. 3. 14:45ㆍ[개발] 기록
구구단 병렬 처리
1. Java 8 이전 : Thread
public class Main{
public static void main(String[] args) {
for(int i = 2 ; i < 10 ; i++ ){
MyThread test = new MyThread(i);
test.start();
}
}
}
@AllArgsConstructor
class MyThread extends Thread {
private int left = -1;
public void run(){
for(int right = 1 ; right < 10 ; right++ ){
System.out.println(Thread.currentThread().getName() + "\t" + left + " * " + right + " = " + (left * right));
}
}
}
Thread-1 3 * 1 = 3
Thread-4 6 * 1 = 6
Thread-1 3 * 2 = 6
Thread-3 5 * 1 = 5
Thread-2 4 * 1 = 4
Thread-0 2 * 1 = 2
Thread-6 8 * 1 = 8
Thread-2 4 * 2 = 8
Thread-3 5 * 2 = 10
Thread-1 3 * 3 = 9
Thread-5 7 * 1 = 7
Thread-4 6 * 2 = 12
Thread-5 7 * 2 = 14
Thread-1 3 * 4 = 12
Thread-3 5 * 3 = 15
Thread-2 4 * 3 = 12
Thread-6 8 * 2 = 16
Thread-7 9 * 1 = 9
Thread-0 2 * 2 = 4
Thread-7 9 * 2 = 18
Thread-6 8 * 3 = 24
Thread-2 4 * 4 = 16
Thread-3 5 * 4 = 20
Thread-1 3 * 5 = 15
Thread-5 7 * 3 = 21
Thread-4 6 * 3 = 18
Thread-5 7 * 4 = 28
Thread-5 7 * 5 = 35
Thread-5 7 * 6 = 42
Thread-1 3 * 6 = 18
Thread-3 5 * 5 = 25
Thread-2 4 * 5 = 20
Thread-6 8 * 4 = 32
Thread-7 9 * 3 = 27
Thread-0 2 * 3 = 6
Thread-7 9 * 4 = 36
Thread-6 8 * 5 = 40
Thread-2 4 * 6 = 24
Thread-3 5 * 6 = 30
Thread-1 3 * 7 = 21
Thread-5 7 * 7 = 49
Thread-4 6 * 4 = 24
Thread-4 6 * 5 = 30
Thread-4 6 * 6 = 36
Thread-4 6 * 7 = 42
Thread-4 6 * 8 = 48
Thread-4 6 * 9 = 54
Thread-5 7 * 8 = 56
Thread-1 3 * 8 = 24
Thread-3 5 * 7 = 35
Thread-2 4 * 7 = 28
Thread-6 8 * 6 = 48
Thread-6 8 * 7 = 56
Thread-7 9 * 5 = 45
Thread-0 2 * 4 = 8
Thread-7 9 * 6 = 54
Thread-6 8 * 8 = 64
Thread-2 4 * 8 = 32
Thread-3 5 * 8 = 40
Thread-1 3 * 9 = 27
Thread-5 7 * 9 = 63
Thread-3 5 * 9 = 45
Thread-2 4 * 9 = 36
Thread-6 8 * 9 = 72
Thread-7 9 * 7 = 63
Thread-0 2 * 5 = 10
Thread-7 9 * 8 = 72
Thread-7 9 * 9 = 81
Thread-0 2 * 6 = 12
Thread-0 2 * 7 = 14
Thread-0 2 * 8 = 16
Thread-0 2 * 9 = 18
Process finished with exit code 0
2. Java 7 이전 : ExecutorService
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main{
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5);
for(int i = 2 ; i < 10 ; i++ ){
final int left = i;
executor.submit(new Runnable(){
@Override
public void run() {
for(int right = 1 ; right < 10 ; right++){
System.out.println(Thread.currentThread().getName() + "\t" + left + " * " + right + " = " + (left * right));
}
}
});
}
executor.shutdown();
}
}
pool-1-thread-1 2 * 1 = 2
pool-1-thread-3 4 * 1 = 4
pool-1-thread-2 3 * 1 = 3
pool-1-thread-3 4 * 2 = 8
pool-1-thread-4 5 * 1 = 5
pool-1-thread-1 2 * 2 = 4
pool-1-thread-1 2 * 3 = 6
pool-1-thread-4 5 * 2 = 10
pool-1-thread-3 4 * 3 = 12
pool-1-thread-5 6 * 1 = 6
pool-1-thread-2 3 * 2 = 6
pool-1-thread-5 6 * 2 = 12
pool-1-thread-3 4 * 4 = 16
pool-1-thread-4 5 * 3 = 15
pool-1-thread-1 2 * 4 = 8
pool-1-thread-4 5 * 4 = 20
pool-1-thread-3 4 * 5 = 20
pool-1-thread-5 6 * 3 = 18
pool-1-thread-2 3 * 3 = 9
pool-1-thread-5 6 * 4 = 24
pool-1-thread-3 4 * 6 = 24
pool-1-thread-3 4 * 7 = 28
pool-1-thread-3 4 * 8 = 32
pool-1-thread-3 4 * 9 = 36
pool-1-thread-4 5 * 5 = 25
pool-1-thread-1 2 * 5 = 10
pool-1-thread-4 5 * 6 = 30
pool-1-thread-3 7 * 1 = 7
pool-1-thread-5 6 * 5 = 30
pool-1-thread-2 3 * 4 = 12
pool-1-thread-5 6 * 6 = 36
pool-1-thread-3 7 * 2 = 14
pool-1-thread-4 5 * 7 = 35
pool-1-thread-4 5 * 8 = 40
pool-1-thread-1 2 * 6 = 12
pool-1-thread-4 5 * 9 = 45
pool-1-thread-3 7 * 3 = 21
pool-1-thread-5 6 * 7 = 42
pool-1-thread-5 6 * 8 = 48
pool-1-thread-5 6 * 9 = 54
pool-1-thread-2 3 * 5 = 15
pool-1-thread-5 9 * 1 = 9
pool-1-thread-3 7 * 4 = 28
pool-1-thread-3 7 * 5 = 35
pool-1-thread-4 8 * 1 = 8
pool-1-thread-1 2 * 7 = 14
pool-1-thread-4 8 * 2 = 16
pool-1-thread-3 7 * 6 = 42
pool-1-thread-5 9 * 2 = 18
pool-1-thread-2 3 * 6 = 18
pool-1-thread-5 9 * 3 = 27
pool-1-thread-3 7 * 7 = 49
pool-1-thread-3 7 * 8 = 56
pool-1-thread-3 7 * 9 = 63
pool-1-thread-4 8 * 3 = 24
pool-1-thread-4 8 * 4 = 32
pool-1-thread-4 8 * 5 = 40
pool-1-thread-4 8 * 6 = 48
pool-1-thread-4 8 * 7 = 56
pool-1-thread-4 8 * 8 = 64
pool-1-thread-4 8 * 9 = 72
pool-1-thread-1 2 * 8 = 16
pool-1-thread-5 9 * 4 = 36
pool-1-thread-2 3 * 7 = 21
pool-1-thread-5 9 * 5 = 45
pool-1-thread-1 2 * 9 = 18
pool-1-thread-5 9 * 6 = 54
pool-1-thread-2 3 * 8 = 24
pool-1-thread-5 9 * 7 = 63
pool-1-thread-2 3 * 9 = 27
pool-1-thread-5 9 * 8 = 72
pool-1-thread-5 9 * 9 = 81
Process finished with exit code 0
3. 자바 8 이후 : ExecutorService + 람다식
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main{
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5);
for(int i = 2 ; i < 10 ; i++ ){
final int left = i;
executor.submit(()->{
for(int right = 1 ; right < 10 ; right++){
System.out.println(Thread.currentThread().getName() + "\t" + left + " * " + right + " = " + (left * right));
}
});
}
executor.shutdown();
}
}
pool-1-thread-1 2 * 1 = 2
pool-1-thread-3 4 * 1 = 4
pool-1-thread-3 4 * 2 = 8
pool-1-thread-2 3 * 1 = 3
pool-1-thread-5 6 * 1 = 6
pool-1-thread-5 6 * 2 = 12
pool-1-thread-5 6 * 3 = 18
pool-1-thread-2 3 * 2 = 6
pool-1-thread-3 4 * 3 = 12
pool-1-thread-1 2 * 2 = 4
pool-1-thread-4 5 * 1 = 5
pool-1-thread-4 5 * 2 = 10
pool-1-thread-4 5 * 3 = 15
pool-1-thread-4 5 * 4 = 20
pool-1-thread-4 5 * 5 = 25
pool-1-thread-1 2 * 3 = 6
pool-1-thread-3 4 * 4 = 16
pool-1-thread-2 3 * 3 = 9
pool-1-thread-5 6 * 4 = 24
pool-1-thread-5 6 * 5 = 30
pool-1-thread-2 3 * 4 = 12
pool-1-thread-3 4 * 5 = 20
pool-1-thread-1 2 * 4 = 8
pool-1-thread-4 5 * 6 = 30
pool-1-thread-1 2 * 5 = 10
pool-1-thread-1 2 * 6 = 12
pool-1-thread-3 4 * 6 = 24
pool-1-thread-2 3 * 5 = 15
pool-1-thread-5 6 * 6 = 36
pool-1-thread-2 3 * 6 = 18
pool-1-thread-2 3 * 7 = 21
pool-1-thread-2 3 * 8 = 24
pool-1-thread-3 4 * 7 = 28
pool-1-thread-1 2 * 7 = 14
pool-1-thread-1 2 * 8 = 16
pool-1-thread-1 2 * 9 = 18
pool-1-thread-4 5 * 7 = 35
pool-1-thread-3 4 * 8 = 32
pool-1-thread-2 3 * 9 = 27
pool-1-thread-5 6 * 7 = 42
pool-1-thread-2 8 * 1 = 8
pool-1-thread-3 4 * 9 = 36
pool-1-thread-4 5 * 8 = 40
pool-1-thread-1 7 * 1 = 7
pool-1-thread-4 5 * 9 = 45
pool-1-thread-3 9 * 1 = 9
pool-1-thread-2 8 * 2 = 16
pool-1-thread-2 8 * 3 = 24
pool-1-thread-5 6 * 8 = 48
pool-1-thread-5 6 * 9 = 54
pool-1-thread-2 8 * 4 = 32
pool-1-thread-3 9 * 2 = 18
pool-1-thread-1 7 * 2 = 14
pool-1-thread-3 9 * 3 = 27
pool-1-thread-3 9 * 4 = 36
pool-1-thread-3 9 * 5 = 45
pool-1-thread-3 9 * 6 = 54
pool-1-thread-2 8 * 5 = 40
pool-1-thread-2 8 * 6 = 48
pool-1-thread-2 8 * 7 = 56
pool-1-thread-2 8 * 8 = 64
pool-1-thread-2 8 * 9 = 72
pool-1-thread-3 9 * 7 = 63
pool-1-thread-1 7 * 3 = 21
pool-1-thread-3 9 * 8 = 72
pool-1-thread-3 9 * 9 = 81
pool-1-thread-1 7 * 4 = 28
pool-1-thread-1 7 * 5 = 35
pool-1-thread-1 7 * 6 = 42
pool-1-thread-1 7 * 7 = 49
pool-1-thread-1 7 * 8 = 56
pool-1-thread-1 7 * 9 = 63
Process finished with exit code 0
4. 자바 8 : List 의 parallelStream
import java.util.ArrayList;
public class Main{
public static void main(String[] args) {
ArrayList<Integer> leftList = new ArrayList<>();
for(int left = 2 ; left < 10 ; left++ ) {
leftList.add(left);
}
leftList.parallelStream().forEach(left ->{
for(int right = 1 ; right < 10 ; right++){
System.out.println(Thread.currentThread().getName() + "\t" + left + " * " + right + " = " + (left * right));
}
});
}
}
main 7 * 1 = 7
main 7 * 2 = 14
main 7 * 3 = 21
main 7 * 4 = 28
main 7 * 5 = 35
main 7 * 6 = 42
ForkJoinPool.commonPool-worker-4 8 * 1 = 8
ForkJoinPool.commonPool-worker-2 9 * 1 = 9
ForkJoinPool.commonPool-worker-13 2 * 1 = 2
ForkJoinPool.commonPool-worker-2 9 * 2 = 18
ForkJoinPool.commonPool-worker-11 3 * 1 = 3
ForkJoinPool.commonPool-worker-4 8 * 2 = 16
ForkJoinPool.commonPool-worker-9 4 * 1 = 4
ForkJoinPool.commonPool-worker-9 4 * 2 = 8
main 7 * 7 = 49
main 7 * 8 = 56
main 7 * 9 = 63
ForkJoinPool.commonPool-worker-9 4 * 3 = 12
ForkJoinPool.commonPool-worker-9 4 * 4 = 16
ForkJoinPool.commonPool-worker-6 6 * 1 = 6
ForkJoinPool.commonPool-worker-4 8 * 3 = 24
ForkJoinPool.commonPool-worker-15 5 * 1 = 5
ForkJoinPool.commonPool-worker-15 5 * 2 = 10
ForkJoinPool.commonPool-worker-15 5 * 3 = 15
ForkJoinPool.commonPool-worker-15 5 * 4 = 20
ForkJoinPool.commonPool-worker-11 3 * 2 = 6
ForkJoinPool.commonPool-worker-11 3 * 3 = 9
ForkJoinPool.commonPool-worker-11 3 * 4 = 12
ForkJoinPool.commonPool-worker-2 9 * 3 = 27
ForkJoinPool.commonPool-worker-2 9 * 4 = 36
ForkJoinPool.commonPool-worker-2 9 * 5 = 45
ForkJoinPool.commonPool-worker-13 2 * 2 = 4
ForkJoinPool.commonPool-worker-13 2 * 3 = 6
ForkJoinPool.commonPool-worker-13 2 * 4 = 8
ForkJoinPool.commonPool-worker-13 2 * 5 = 10
ForkJoinPool.commonPool-worker-13 2 * 6 = 12
ForkJoinPool.commonPool-worker-13 2 * 7 = 14
ForkJoinPool.commonPool-worker-2 9 * 6 = 54
ForkJoinPool.commonPool-worker-11 3 * 5 = 15
ForkJoinPool.commonPool-worker-15 5 * 5 = 25
ForkJoinPool.commonPool-worker-4 8 * 4 = 32
ForkJoinPool.commonPool-worker-4 8 * 5 = 40
ForkJoinPool.commonPool-worker-4 8 * 6 = 48
ForkJoinPool.commonPool-worker-6 6 * 2 = 12
ForkJoinPool.commonPool-worker-9 4 * 5 = 20
ForkJoinPool.commonPool-worker-6 6 * 3 = 18
ForkJoinPool.commonPool-worker-4 8 * 7 = 56
ForkJoinPool.commonPool-worker-15 5 * 6 = 30
ForkJoinPool.commonPool-worker-11 3 * 6 = 18
ForkJoinPool.commonPool-worker-11 3 * 7 = 21
ForkJoinPool.commonPool-worker-2 9 * 7 = 63
ForkJoinPool.commonPool-worker-13 2 * 8 = 16
ForkJoinPool.commonPool-worker-2 9 * 8 = 72
ForkJoinPool.commonPool-worker-11 3 * 8 = 24
ForkJoinPool.commonPool-worker-15 5 * 7 = 35
ForkJoinPool.commonPool-worker-4 8 * 8 = 64
ForkJoinPool.commonPool-worker-6 6 * 4 = 24
ForkJoinPool.commonPool-worker-6 6 * 5 = 30
ForkJoinPool.commonPool-worker-9 4 * 6 = 24
ForkJoinPool.commonPool-worker-9 4 * 7 = 28
ForkJoinPool.commonPool-worker-9 4 * 8 = 32
ForkJoinPool.commonPool-worker-6 6 * 6 = 36
ForkJoinPool.commonPool-worker-4 8 * 9 = 72
ForkJoinPool.commonPool-worker-15 5 * 8 = 40
ForkJoinPool.commonPool-worker-11 3 * 9 = 27
ForkJoinPool.commonPool-worker-2 9 * 9 = 81
ForkJoinPool.commonPool-worker-13 2 * 9 = 18
ForkJoinPool.commonPool-worker-15 5 * 9 = 45
ForkJoinPool.commonPool-worker-6 6 * 7 = 42
ForkJoinPool.commonPool-worker-6 6 * 8 = 48
ForkJoinPool.commonPool-worker-6 6 * 9 = 54
ForkJoinPool.commonPool-worker-9 4 * 9 = 36
Process finished with exit code 0
parallelStream 이 내부적으로는 자바 7 의 ForkJoinPool 을 이용해서 구현되있음을 확인할 수 있다.
ForkJoinPool 에 관한 내용은 아래 글을 참조
https://okky.kr/article/345720
5. 자바 8 : List 의 parallelStream + Thread 크기 지정
import java.util.ArrayList;
import java.util.concurrent.ForkJoinPool;
public class Main{
public static void main(String[] args) throws Exception{
ArrayList<Integer> leftList = new ArrayList<>();
for(int left = 2 ; left < 10 ; left++ ) {
leftList.add(left);
}
ForkJoinPool forkjoinPool = new ForkJoinPool(5);
forkjoinPool.submit(() -> {
leftList.parallelStream().forEach(left -> {
for (int right = 1; right < 10; right++) {
System.out.println(Thread.currentThread().getName() + "\t" + left + " * " + right + " = " + (left * right));
}
});
});
Thread.sleep(1000);
}
}
ForkJoinPool-1-worker-1 7 * 1 = 7
ForkJoinPool-1-worker-1 7 * 2 = 14
ForkJoinPool-1-worker-4 3 * 1 = 3
ForkJoinPool-1-worker-4 3 * 2 = 6
ForkJoinPool-1-worker-3 9 * 1 = 9
ForkJoinPool-1-worker-3 9 * 2 = 18
ForkJoinPool-1-worker-2 4 * 1 = 4
ForkJoinPool-1-worker-2 4 * 2 = 8
ForkJoinPool-1-worker-2 4 * 3 = 12
ForkJoinPool-1-worker-2 4 * 4 = 16
ForkJoinPool-1-worker-2 4 * 5 = 20
ForkJoinPool-1-worker-2 4 * 6 = 24
ForkJoinPool-1-worker-2 4 * 7 = 28
ForkJoinPool-1-worker-2 4 * 8 = 32
ForkJoinPool-1-worker-3 9 * 3 = 27
ForkJoinPool-1-worker-3 9 * 4 = 36
ForkJoinPool-1-worker-4 3 * 3 = 9
ForkJoinPool-1-worker-4 3 * 4 = 12
ForkJoinPool-1-worker-1 7 * 3 = 21
ForkJoinPool-1-worker-1 7 * 4 = 28
ForkJoinPool-1-worker-1 7 * 5 = 35
ForkJoinPool-1-worker-1 7 * 6 = 42
ForkJoinPool-1-worker-5 6 * 1 = 6
ForkJoinPool-1-worker-5 6 * 2 = 12
ForkJoinPool-1-worker-5 6 * 3 = 18
ForkJoinPool-1-worker-1 7 * 7 = 49
ForkJoinPool-1-worker-1 7 * 8 = 56
ForkJoinPool-1-worker-1 7 * 9 = 63
ForkJoinPool-1-worker-4 3 * 5 = 15
ForkJoinPool-1-worker-4 3 * 6 = 18
ForkJoinPool-1-worker-1 5 * 1 = 5
ForkJoinPool-1-worker-3 9 * 5 = 45
ForkJoinPool-1-worker-3 9 * 6 = 54
ForkJoinPool-1-worker-2 4 * 9 = 36
ForkJoinPool-1-worker-3 9 * 7 = 63
ForkJoinPool-1-worker-3 9 * 8 = 72
ForkJoinPool-1-worker-3 9 * 9 = 81
ForkJoinPool-1-worker-1 5 * 2 = 10
ForkJoinPool-1-worker-4 3 * 7 = 21
ForkJoinPool-1-worker-5 6 * 4 = 24
ForkJoinPool-1-worker-5 6 * 5 = 30
ForkJoinPool-1-worker-5 6 * 6 = 36
ForkJoinPool-1-worker-5 6 * 7 = 42
ForkJoinPool-1-worker-5 6 * 8 = 48
ForkJoinPool-1-worker-4 3 * 8 = 24
ForkJoinPool-1-worker-1 5 * 3 = 15
ForkJoinPool-1-worker-1 5 * 4 = 20
ForkJoinPool-1-worker-3 2 * 1 = 2
ForkJoinPool-1-worker-3 2 * 2 = 4
ForkJoinPool-1-worker-3 2 * 3 = 6
ForkJoinPool-1-worker-2 8 * 1 = 8
ForkJoinPool-1-worker-3 2 * 4 = 8
ForkJoinPool-1-worker-1 5 * 5 = 25
ForkJoinPool-1-worker-4 3 * 9 = 27
ForkJoinPool-1-worker-5 6 * 9 = 54
ForkJoinPool-1-worker-1 5 * 6 = 30
ForkJoinPool-1-worker-1 5 * 7 = 35
ForkJoinPool-1-worker-3 2 * 5 = 10
ForkJoinPool-1-worker-2 8 * 2 = 16
ForkJoinPool-1-worker-3 2 * 6 = 12
ForkJoinPool-1-worker-1 5 * 8 = 40
ForkJoinPool-1-worker-3 2 * 7 = 14
ForkJoinPool-1-worker-3 2 * 8 = 16
ForkJoinPool-1-worker-3 2 * 9 = 18
ForkJoinPool-1-worker-2 8 * 3 = 24
ForkJoinPool-1-worker-1 5 * 9 = 45
ForkJoinPool-1-worker-2 8 * 4 = 32
ForkJoinPool-1-worker-2 8 * 5 = 40
ForkJoinPool-1-worker-2 8 * 6 = 48
ForkJoinPool-1-worker-2 8 * 7 = 56
ForkJoinPool-1-worker-2 8 * 8 = 64
ForkJoinPool-1-worker-2 8 * 9 = 72
Process finished with exit code 0
*) parallelStream 은 기본적으로 병렬 처리를 하지만 stream 이 마무리 될 때까지 block 이 된다. -> wait 해줄 필요 x
*) ExecutorService 와 ForkJoinPool 은 awaitTerminated 나 invokeAll을 사용해서 wait 해줘야한다.
성능에 관하여.
https://hamait.tistory.com/612
'[개발] 기록' 카테고리의 다른 글
mvn vs mvnw (0) | 2019.06.26 |
---|---|
자바 8 Stream (0) | 2019.06.06 |
Java Optional class (0) | 2019.04.25 |
Reactive connection with DB (0) | 2019.04.18 |
Lombok을 사용할 때 List 타입 멤버변수 오버라이딩 (0) | 2019.04.16 |