본문 바로가기

미국유학/CS 601 Principles of Software Dev

241001 수업 , Thread

thread, start, run 알아야 되고

 

 

callable 알아야 되고 , Future task 알아야 되고

 

 

 

 

 

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를 사용하여 스레드 풀을 관리하고, 작업을 효율적으로 처리합니다. 주요 장점은 다음과 같습니다.

  1. 스레드 관리의 간소화:
    • 스레드 풀을 사용함으로써 스레드 생성과 종료를 자동으로 관리할 수 있습니다.
    • 스레드 풀은 유휴 상태의 스레드를 재사용할 수 있어 성능 최적화에 도움이 됩니다.
  2. 비동기 작업 처리:
    • 각 행에 대한 작업은 비동기적으로 처리됩니다. 즉, 작업이 완료될 때까지 기다리지 않고 다음 작업을 제출할 수 있습니다.
    • 결과는 Future 객체를 통해 나중에 받을 수 있습니다.
  3. Callable을 통한 결과 반환:
    • Callable 인터페이스는 Runnable과 달리 결과를 반환할 수 있습니다. 각 스레드는 각 행의 최대값을 계산하고, 그 결과를 Future 객체를 통해 비동기적으로 반환합니다.
  4. Future 객체를 통한 결과 처리:
    • Future.get() 메서드는 블로킹 호출로, 결과가 준비될 때까지 대기합니다. 스레드가 완료된 후 그 결과를 받아와 최종적으로 전체 배열에서 최대값을 구합니다.

정리

  1. 멀티스레딩을 ExecutorService로 관리: ExecutorService를 사용해 스레드 풀을 관리하며, 각 행에 대한 최대값을 병렬로 계산합니다.
  2. 비동기 작업 처리: Callable 인터페이스를 사용하여 비동기 작업을 정의하고, 그 결과를 Future 객체로 받아옵니다.
  3. 결과 취합: 각 스레드가 계산한 최대값을 Future.get()을 통해 받아와, 전체 배열의 최대값을 계산합니다.
  4. 스레드 풀 종료: 모든 작업이 완료된 후 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