package multithreading.basic;
/**
* Creates NUM_ROWS threads to search for the maximum value of a large matrix. Each
* thread searches for max in one row of the matrix. Based on the example from
* http://www.ibm.com/developerworks/java/tutorials/j-threads/j-threads.html
*/
public class SolvingForMax {
public final static int NUM_ROWS = 10;
/** Inner class that represents a worker thread that computes the maximum in the given 1D array */
private static class WorkerThread extends Thread {
double max = Double.MIN_VALUE;
double[] row;
public WorkerThread(double[] row) {
this.row = row;
}
/** Find the maximum value in the given row
*
*/
@Override
public void run() {
for (int i = 0; i < row.length; i++)
max = Math.max(max, row[i]);
}
/**
*
* @return maximum for this row
*/
public double getMax() {
return max;
}
}
public static void main(String[] args) {
double [][] bigMatrix = generateBigMatrix(NUM_ROWS, 1000000);
WorkerThread[] threads = new WorkerThread[bigMatrix.length];
double max = Double.MIN_VALUE;
// Give each thread a row of the matrix to work with
for (int i = 0; i < NUM_ROWS; i++) {
threads[i] = new WorkerThread(bigMatrix[i]);
threads[i].start();
}
// Wait for each thread to finish
try {
for (int i = 0; i < NUM_ROWS; i++) {
threads[i].join();
max = Math.max(max, threads[i].getMax());
}
} catch (InterruptedException e) {
System.out.println("The thread was interrupted. ");
}
System.out.println("Maximum value was " + max);
}
/**
*
* @param n the number of rows in the matrix
* @param m the number of columns in the matrix
* @return the matrix n by m of random values in the range from 0 to 1.
*/
public static double[][] generateBigMatrix(int n, int m) {
double[][] matrix = new double[n][m];
for (int row = 0; row < matrix.length; row++) {
for (int col = 0; col < matrix[row].length; col++) {
matrix[row][col] = Math.random();
// System.out.print(matrix[row][col] + "\t");
}
// System.out.println();
}
return matrix;
}
}
- 이 프로그램은 2차원 배열의 각 행에 대해 병렬로 최대값을 계산하는 구조를 가지고 있습니다.
- 각 행에 대해 별도의 스레드가 할당되어 최대값을 계산하며, 이 작업은 병렬로 이루어집니다.
- 모든 스레드가 작업을 완료할 때까지 메인 스레드는 기다린 후, 각각의 스레드에서 계산된 최대값을 취합합니다.
- 최종적으로 전체 배열에서의 최대값을 출력합니다.
package multithreading.poolOfThreads;
import java.util.concurrent.*;
/**
* Creates NUM_ROWS threads to search for the maximum value of a large matrix. Each
* thread searches for max in one row of the matrix. Based on the example from
* http://www.ibm.com/developerworks/java/tutorials/j-threads/j-threads.html
* Uses concurrent package.
*/
public class SolvingForMaxUsingExecutor {
public final static int NUM_ROWS = 10;
/** Inner class that represents a worker thread that computes the maximum in the given 1D array */
private static class Worker implements Callable {
double max = Double.MIN_VALUE;
double[] row;
public Worker(double[] row) {
this.row = row;
}
/** Find the maximum value in the given row
*
*/
@Override
public Object call() {
for (int i = 0; i < row.length; i++)
max = Math.max(max, row[i]);
return max;
}
}
public static void main(String[] args) {
double max = Double.MIN_VALUE;
double [][] bigMatrix = generateBigMatrix(NUM_ROWS, 1000000);
ExecutorService exec = Executors.newCachedThreadPool();
try {
Future<Double>[] results = new FutureTask[NUM_ROWS];
for (int i = 0; i < NUM_ROWS; i++) {
Future<Double> res = exec.submit(new Worker(bigMatrix[i]));
results[i] = res;
}
for (int i = 0; i < NUM_ROWS; i++) {
double val = results[i].get(); // will wait for the result to be ready
if (val > max)
max = val;
}
}
catch (Exception e) {
System.out.println(e);
}
exec.shutdown();
try {
exec.awaitTermination(1, TimeUnit.MINUTES);
} catch (InterruptedException e) {
System.out.println(e);
}
System.out.println("Maximum value was " + max);
}
/**
*
* @param n the number of rows in the matrix
* @param m the number of columns in the matrix
* @return the matrix n by m of random values in the range from 0 to 1.
*/
public static double[][] generateBigMatrix(int n, int m) {
double[][] matrix = new double[n][m];
for (int row = 0; row < matrix.length; row++) {
for (int col = 0; col < matrix[row].length; col++) {
matrix[row][col] = Math.random();
//System.out.print(matrix[row][col] + "\t");
}
//System.out.println();
}
return matrix;
}
}
Executor Framework와 멀티스레딩의 장점
이 코드는 Executor Framework를 사용하여 스레드 풀을 관리하고, 작업을 효율적으로 처리합니다. 주요 장점은 다음과 같습니다.
- 스레드 관리의 간소화:
- 스레드 풀을 사용함으로써 스레드 생성과 종료를 자동으로 관리할 수 있습니다.
- 스레드 풀은 유휴 상태의 스레드를 재사용할 수 있어 성능 최적화에 도움이 됩니다.
- 비동기 작업 처리:
- 각 행에 대한 작업은 비동기적으로 처리됩니다. 즉, 작업이 완료될 때까지 기다리지 않고 다음 작업을 제출할 수 있습니다.
- 결과는 Future 객체를 통해 나중에 받을 수 있습니다.
- Callable을 통한 결과 반환:
- Callable 인터페이스는 Runnable과 달리 결과를 반환할 수 있습니다. 각 스레드는 각 행의 최대값을 계산하고, 그 결과를 Future 객체를 통해 비동기적으로 반환합니다.
- Future 객체를 통한 결과 처리:
- Future.get() 메서드는 블로킹 호출로, 결과가 준비될 때까지 대기합니다. 스레드가 완료된 후 그 결과를 받아와 최종적으로 전체 배열에서 최대값을 구합니다.
정리
- 멀티스레딩을 ExecutorService로 관리: ExecutorService를 사용해 스레드 풀을 관리하며, 각 행에 대한 최대값을 병렬로 계산합니다.
- 비동기 작업 처리: Callable 인터페이스를 사용하여 비동기 작업을 정의하고, 그 결과를 Future 객체로 받아옵니다.
- 결과 취합: 각 스레드가 계산한 최대값을 Future.get()을 통해 받아와, 전체 배열의 최대값을 계산합니다.
- 스레드 풀 종료: 모든 작업이 완료된 후 ExecutorService를 정상적으로 종료합니다.
이 방식은 스레드 생성을 효율적으로 관리할 수 있어 대규모 데이터 처리 시 성능을 향상시킬 수 있습니다.
+no quiz on thursday
+Json Example, Junit 5 example post 했으니까 봐보기. (...arguments 문법*)
+there is lab on Friday
+proejct 2 관련 -> 자료구조 LinkedHashMap 써도 됨
Junit 5 example
import junit.Circle;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import static org.junit.jupiter.api.Assertions.assertEquals;
/** Example of how write parameterized tests */
public class CircleTest {
@ParameterizedTest
@MethodSource("loadTestDataArea")
@DisplayName("Test area: ")
void testArea(double inputRadius, double expectedArea) {
System.out.println("Testing area calculation");
assertEquals(expectedArea, new Circle(inputRadius).area(), 0.0001);
}
@ParameterizedTest
@MethodSource("loadTestDataPerimeter")
@DisplayName("Test perimeter:")
void testPerimeter(double inputRadius, double expectedPerimeter) {
System.out.println("Testing perimeter calculation");
assertEquals(expectedPerimeter, new Circle(inputRadius).perimeter(), 0.0001);
}
static Arguments[] loadTestDataArea() {
return new Arguments[] {
Arguments.of(1, Math.PI),
Arguments.of(2, 4 * Math.PI)
};
}
static Arguments[] loadTestDataPerimeter() {
return new Arguments[] {
Arguments.of(1, 2 * Math.PI),
Arguments.of(2, 4 * Math.PI)
};
}
}
'미국유학 > CS 601 Principles of Software Dev' 카테고리의 다른 글
10.4 Lock (0) | 2024.10.05 |
---|---|
241003 PSD - Multithreading, Synchronization (2) | 2024.10.04 |
Polymorphism (240905) (0) | 2024.09.06 |
240903 Iterator (0) | 2024.09.04 |
1st quiz (0) | 2024.08.30 |