태그 보관물: Pattern

POSA 1 – 마스터-슬레이브(Master-Slave) 패턴

마스터-슬레이브(Master-Slave) 패턴은 마스터(Master)가 슬레이브(Slave)에게 작업을 분산하고, 슬레이브가 처리한 결과로 최종 결과를 계산하는 패턴이다. 즉, 마스터는 작업을 쪼개고, 슬레이브에게 쪼갠 작업을 분배하고, 결과를 계산하는 역할을 한다. 그리고 슬레이브는 마스터의 작업 요청을 처리하고, 결과를 리턴한다.

그래서 위 패턴의 형태로 간단한 코드를 작성해 보자. 예제는 1부터 10까지의 factorial을 10개의 작업(Job)으로 나누고, 나눠진 작업의 결과를 마스터가 더해서 마지막 결과를 보여주는 예제이다.

아래의 MSClient는 클라이언트와 마스터 역할을 담당한다. JobThread는 슬레이브 역할을 담당한다.

– MSClient.java

import java.util.List;
import java.util.ArrayList;
import java.util.concurrent.Future;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ExecutionException;
import java.math.BigInteger;

public class MSClient {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
           
        ArrayList jobArray = new ArrayList();
        ExecutorService executor =  Executors.newFixedThreadPool(10);
           
        for (int i = 1; i <= 10; i++) {
            jobArray.add(new JobThread(i));
        }
       
        List<Future> allResults = null;
       
        long totalSum = 0;
       
        try {
            allResults = executor.invokeAll(jobArray);
                         
            for(int i=0; i < allResults.size(); i++) {
                totalSum += allResults.get(i).get().longValue();
                System.out.println((i+1) + “! is ” + allResults.get(i).get());
            }
           
            System.out.println(“Total Value is ” + totalSum);

        } catch (InterruptedException e) {
            System.out.println(“Interrupted”);
        } catch (ExecutionException e) {
            System.out.println( “Execution exception”);
        }
       
        executor.shutdown();
    }
}

– JobThread.java

import java.util.concurrent.Callable;
import java.math.BigInteger;

public class JobThread implements Callable {
    //
    private int min = 1;
    //
    private int value = 0;
   
    public JobThread(int value) {
        this.value = value;
    }
   
    @Override
    public BigInteger call() throws Exception {
       
        BigInteger fac = BigInteger.valueOf(this.min);
       
        for (int i = 1; i <= this.value; i++)
            fac = fac.multiply(BigInteger.valueOf(i));
   
        return fac;
    }
}