    001/*
    002 * Copyright (c) 2009 The openGion Project.
    003 *
    004 * Licensed under the Apache License, Version 2.0 (the "License");
    005 * you may not use this file except in compliance with the License.
    006 * You may obtain a copy of the License at
    007 *
    008 *     http://www.apache.org/licenses/LICENSE-2.0
    009 *
    010 * Unless required by applicable law or agreed to in writing, software
    011 * distributed under the License is distributed on an "AS IS" BASIS,
    012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
    013 * either express or implied. See the License for the specific language
    014 * governing permissions and limitations under the License.
    015 */
    016package org.opengion.hayabusa.report2;
    017
    018import java.util.HashMap;
    019import java.util.Map;
    020
    021/**
    022 * 帳票処理を行う各スレッドを管理するクラスです。
    023 *
    024 * 各スレッドは、内部的にプールされます。
    025 * スレッドのIDはOOoQueue#getThreadId()で返される値です。
    026 * スレッドが生成されるタイミングは、そのIDで初めてスタック要求が来た(insertQueue()が呼ばれた)時です。
    027 *
    028 * 指定のスレッドを終了するには、funishThread( key )を呼び出します。
    029 * 全てのスレッドを終了するには、funishAllThreads()を呼び出します。
    030 *
    031 * 現時点での実装では、生成されたスレッドに対しての監視は行っていません。
    032 * これは、特定のスレッドがフリーズした際、外部から強制終了を行おうとすると、
    033 * 監視スレッドもフリーズしてしまう問題があるためです。
    034 * (但し、1つのsoffice.binのプロセスに対してシリアルに対して処理している限りでは、
    035 *  フリーズ問題は発生しないようです)
    036 *
    037 * @og.group 帳票システム
    038 *
    039 * @version  4.0
    040 * @author   Hiroki.Nakamura
    041 * @since    JDK1.6
    042 */
    043public final class ExecThreadManager {
    044
    045        /**
    046         * スレッドプール
    047         */
    048        private static final Map<String, ExecThread>    pool    = new HashMap<String, ExecThread>();
    049        private static boolean debug    = false; // 4.3.0.0 (2008/07/15) デバッグ追加
    050
    051        /**
    052         * オブジェクトの生成を禁止します
    053         */
    054        private ExecThreadManager() {}
    055
    056        /**
    057         * キューを該当するスレッドにスタックする
    058         *
    059         * @og.rev 4.3.0.0 (2008/07/15) スレッドIDにシステムIDを付加
    060         *
    061         * @param       queue   ExecQueueオブジェクト
    062         */
    063        public static void insertQueue( final ExecQueue queue ) {
    064                // 4.3.3.6 (2008/11/15) この部分は不要なので元に戻します
    065                ExecThread oet = getExecThread( queue.getThreadId() );
    066                oet.stackQueue( queue );
    067        }
    068
    069        /**
    070         * キューを該当するスレッドにスタックする
    071         *
    072         * このメソッドでは、既に同じスレッドが存在するかどうかをチェックせずに必ず
    073         * 新しいスレッドを生成し、キューを処理します。
    074         * また、処理が完了した後、そのスレッドは、WAITすることなく終了します。
    075         *
    076         * @og.rev 5.1.6.0 (2010/05/01) 新規作成
    077         *
    078         * @param       queue   ExecQueueオブジェクト
    079         */
    080        public static void insertQueueOnNewThread( final ExecQueue queue ) {
    081                ExecThread oet = new ExecThread( queue.getThreadId(), debug );
    082                oet.start();
    083                System.out.println( "[INFO]THREAD CREATED:THREAD-ID=" + queue.getThreadId() );
    084                oet.stackQueue( queue );
    085                oet.finishAfterExec();
    086        }
    087
    088        /**
    089         * 該当するスレッドIDを持つスレッドを取得します。
    090         * スレッドプールに存在しない場合は、新規に作成されます。
    091         *
    092         * @param       threadId        スレッドID
    093         *
    094         * @return      ExecThreadスレッド
    095         */
    096        private static ExecThread getExecThread( final String threadId ) {
    097                ExecThread oet = null;
    098                synchronized( pool ) {
    099                        oet = pool.get( threadId );
    100
    101                        // スレッドが終了している場合は、再度作成
    102                        if( oet != null && !oet.isAlive() ) {
    103                                pool.remove( threadId );
    104                                oet = null;
    105                        }
    106
    107                        if( oet == null ) {
    108                                // oet = new ExecThread( threadId );
    109                                oet = new ExecThread( threadId, debug );
    110                                oet.start();
    111                                System.out.println( "[INFO]THREAD CREATED:THREAD-ID=" + threadId );
    112                                pool.put( threadId, oet );
    113                        }
    114                }
    115
    116                return oet;
    117        }
    118
    119        /**
    120         * 全てのスレッドを終了します。
    121         *
    122         */
    123        public static void finishAllThreads() {
    124                synchronized( pool ) {
    125                        for( ExecThread oet : pool.values() ) {
    126                                oet.finish();
    127                        }
    128                        pool.clear();
    129                        System.out.println( "[INFO]ALL THREADS FINISHED" );
    130                }
    131        }
    132
    133        /**
    134         * 指定のスレッドを終了します。
    135         *
    136         * @param threadId スレッドID
    137         */
    138        public static void finishThread( final String threadId ) {
    139                synchronized( pool ) {
    140                        ExecThread oet = pool.remove( threadId );
    141                        if( oet != null ) {
    142                                oet.finish();
    143                                System.out.println( "[INFO]THREAD CREATED:THREAD-ID=" + threadId );
    144                        }
    145                }
    146        }
    147
    148        /**
    149         * スレッド情報のマップを返します。
    150         *
    151         * @return      スレッド情報のマップ
    152         */
    153        public static Map<String, String> getThreadInfo() {
    154                Map<String, String> info = new HashMap<String, String>();
    155                synchronized( pool ) {
    156                        for( Map.Entry<String, ExecThread> entry : pool.entrySet() ) {
    157                                info.put( entry.getKey(), entry.getValue().toString() );
    158                        }
    159                }
    160                return info;
    161        }
    162
    163        /**
    164         * デバッグフラグの設定
    165         *
    166         * @og.rev  4.3.0.0 (2008/07/15) デバッグ追加
    167         *
    168         * @param   flag デバッグフラグ [true:デバッグ/false:通常]
    169         */
    170        public static void setDebug ( final boolean flag ){
    171                debug = flag;
    172        }
    173}