Java5、6での並列処理(マルチスレッド)その2

その2といっても、やっていることは同じ。
もう少し踏み込んでみたソース。

CPUの数を取得したり、
例外時にサービスの即時shutdownをしたり、
Callableにコンストラクタで引数を渡したり、など。
前のよりもちょっとだけ実用向き。

package sample;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class OrderWork {
    class Owner {
        public void exec() throws Exception{
            long start = System.currentTimeMillis();
            List<SampleDTO> alllist = new ArrayList<SampleDTO>(); 
            // TODO 自動生成されたメソッド・スタブ
            int cpucount = Runtime.getRuntime().availableProcessors();
            System.out.println(cpucount);
            
            ExecutorService executor = Executors.newFixedThreadPool(cpucount);
            CompletionService<SampleDTO> completion = 
                new ExecutorCompletionService<SampleDTO>(executor);
            int count = 10000;
            for (int i=0;i<count;i++) {
                if (i % 2 == 0) {
                    completion.submit(new WorkerA(i));  
                }else{
                    completion.submit(new WorkerB(i));
                }
            }
            executor.shutdown();

            for (int i=0; i <count; i++) {
                try {
                    Future<SampleDTO> future = completion.take();
                    SampleDTO result = future.get();
                    alllist.add(result);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    continue;
                } catch (ExecutionException e) {
                    executor.shutdownNow();
                    throw new Exception(e.getCause());
                }
            }

            Collections.sort(alllist,new Comparator<SampleDTO>(){
                @Override
                public int compare(SampleDTO arg0, SampleDTO arg1) {
                    return arg0.getOrder() - arg1.getOrder();
                }
            });

            StringBuilder sb = new StringBuilder();
            for(SampleDTO dto : alllist){
                sb.append(dto.getName());
            }

            System.out.println(sb.toString());
        }
    }

    /**
     * @param args
     * @throws Exception 
     */
    public static void main(String[] args) throws Exception {
        long start = System.currentTimeMillis();
        // TODO 自動生成されたメソッド・スタブ
        Owner on = new OrderWork().new Owner();
        on.exec();
        long end = System.currentTimeMillis();
        System.out.println(end-start);
    }

    public class SampleDTO {
        private int order;
        public int getOrder() {
            return order;
        }

        public void setOrder(int order) {
            this.order = order;
        }

        private String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }

    class WorkerA extends BaseWorker implements Callable<SampleDTO> {
        
        WorkerA(int order) {
            this.order = order;
        }
        @Override
        public SampleDTO call() throws Exception {
            SampleDTO dto = new SampleDTO();
            dto.setName("aaa"+order);
            dto.setOrder(order);
            return dto;
        }
    }
    class WorkerB extends BaseWorker implements Callable<SampleDTO> {
        WorkerB(int order) {
            this.order = order;
        }
        @Override
        public SampleDTO call() throws Exception {
            SampleDTO dto = new SampleDTO();
            dto.setName("bbb"+order);
            dto.setOrder(order);
            return dto;
        }
    }

    class BaseWorker {
        protected int order;
        public int getOrder() {
            return order;
        }
        public void setOrder(int order) {
            this.order = order;
        }
    }
    
}