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 static final int REPORT_THREAD_CHECK_INTERVAL = 1000 * 2; 055 056// /** 057// * OOoがクラッシュしていると判断される停止時間 058// */ 059// private static final int REPORT_THREAD_CRASH_TIME = 1000 * 2; 060 061// /** 062// * チェック用のスレッドを開始します 063// */ 064// static { 065// checkThreads(); 066// } 067 068 /** 069 * オブジェクトの生成を禁止します 070 */ 071 private ExecThreadManager() {} 072 073 /** 074 * キューを該当するスレッドにスタックする 075 * 076 * @og.rev 4.3.0.0 (2008/07/15) スレッドIDにシステムIDを付加 077 * 078 * @param queue ExecQueueオブジェクト 079 */ 080 public static void insertQueue( final ExecQueue queue ) { 081 // 4.3.3.6 (2008/11/15) この部分は不要なので元に戻します 082 ExecThread oet = getExecThread( queue.getThreadId() ); 083// ExecThread oet = getExecThread( queue.getSystemId() + "_" + queue.getThreadId() ); // 4.3.0.0 (2008/07/15) システムIDをスレッドIDに付加します。 084 oet.stackQueue( queue ); 085 } 086 087 /** 088 * キューを該当するスレッドにスタックする 089 * 090 * このメソッドでは、既に同じスレッドが存在するかどうかをチェックせずに必ず 091 * 新しいスレッドを生成し、キューを処理します。 092 * また、処理が完了した後、そのスレッドは、WAITすることなく終了します。 093 * 094 * @og.rev 5.1.6.0 (2010/05/01) 新規作成 095 * 096 * @param queue ExecQueueオブジェクト 097 */ 098 public static void insertQueueOnNewThread( final ExecQueue queue ) { 099 ExecThread oet = new ExecThread( queue.getThreadId(), debug ); 100 oet.start(); 101 System.out.println( "[INFO]THREAD CREATED:THREAD-ID=" + queue.getThreadId() ); 102 oet.stackQueue( queue ); 103 oet.finishAfterExec(); 104 } 105 106 /** 107 * 該当するスレッドIDを持つスレッドを取得します。 108 * スレッドプールに存在しない場合は、新規に作成されます。 109 * 110 * @param threadId スレッドID 111 * 112 * @return ExecThreadスレッド 113 */ 114 private static ExecThread getExecThread( final String threadId ) { 115 ExecThread oet = null; 116 synchronized( pool ) { 117 oet = pool.get( threadId ); 118 119 // スレッドが終了している場合は、再度作成 120 if( oet != null && !oet.isAlive() ) { 121 pool.remove( threadId ); 122 oet = null; 123 } 124 125 if( oet == null ) { 126 // oet = new ExecThread( threadId ); 127 oet = new ExecThread( threadId, debug ); 128 oet.start(); 129 System.out.println( "[INFO]THREAD CREATED:THREAD-ID=" + threadId ); 130 pool.put( threadId, oet ); 131 } 132 } 133 134 return oet; 135 } 136 137 /** 138 * 全てのスレッドを終了します。 139 * 140 */ 141 public static void finishAllThreads() { 142 synchronized( pool ) { 143 for( ExecThread oet : pool.values() ) { 144 oet.finish(); 145 } 146 pool.clear(); 147 System.out.println( "[INFO]ALL THREADS FINISHED" ); 148 } 149 } 150 151 /** 152 * 指定のスレッドを終了します。 153 * 154 * @param threadId スレッドID 155 */ 156 public static void finishThread( final String threadId ) { 157 synchronized( pool ) { 158 ExecThread oet = pool.remove( threadId ); 159 if( oet != null ) { 160 oet.finish(); 161 System.out.println( "[INFO]THREAD CREATED:THREAD-ID=" + threadId ); 162 } 163 } 164 } 165 166 /** 167 * スレッド情報のマップを返します。 168 * 169 * @return スレッド情報のマップ 170 */ 171 public static Map<String, String> getThreadInfo() { 172 Map<String, String> info = new HashMap<String, String>(); 173 synchronized( pool ) { 174 for( Map.Entry<String, ExecThread> entry : pool.entrySet() ) { 175 info.put( entry.getKey(), entry.getValue().toString() ); 176 } 177 } 178 return info; 179 } 180 181 /** 182 * デバッグフラグの設定 183 * 184 * @og.rev 4.3.0.0 (2008/07/15) デバッグ追加 185 * 186 * @param flag デバッグフラグ [true:デバッグ/false:通常] 187 */ 188 public static void setDebug ( final boolean flag ){ 189 debug = flag; 190 } 191 192// /** 193// * 監視用のスレッドを開始します。 194// * 195// */ 196// private static void checkThreads() { 197// new Thread() { 198// public void run() { 199// 200// while( true ) { 201// try { 202// Thread.sleep( REPORT_THREAD_CHECK_INTERVAL ); 203// } 204// catch( InterruptedException e ) {} 205// 206// synchronized( pool ) { 207// for( Map.Entry<String, ExecThread> entry : pool.entrySet() ) { 208// String id = entry.getKey(); 209// ExecThread oet = entry.getValue(); 210// 211// System.out.println(oet.getExecTime()); 212// 213// if( oet.getExecTime() > REPORT_THREAD_CRASH_TIME ) { 214// System.out.println( "【監視】スレッドID=" + id + "がクラッシュしている可能性がありますので、割込要求を発行します。(処理時間=" + String.valueOf( oet.getExecTime() ) + ")" ); 215// oet.interrupt(); 216// } 217// } 218// } 219// } 220// 221// } 222// }.start(); 223// } 224 225}