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.concurrent.ConcurrentMap; // 6.4.3.3 (2016/03/04) 019import java.util.concurrent.ConcurrentHashMap; // 6.4.3.3 (2016/03/04) 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 /** 6.4.3.1 (2016/02/12) 一連の処理で同期を取りたいので、 ConcurrentHashMap は使いません。 */ 046 private static final ConcurrentMap<String, ExecThread> EXEC_POOL = new ConcurrentHashMap<>(); // 6.4.3.3 (2016/03/04) 047 private static boolean debug ; // 4.3.0.0 (2008/07/15) デバッグ追加 048 049 /** 050 * オブジェクトの生成を禁止します 051 */ 052 private ExecThreadManager() {} 053 054 /** 055 * キューを該当するスレッドにスタックする。 056 * 057 * @og.rev 4.3.0.0 (2008/07/15) スレッドIDにシステムIDを付加 058 * 059 * @param queue ExecQueueオブジェクト 060 */ 061 public static void insertQueue( final ExecQueue queue ) { 062 // 4.3.3.6 (2008/11/15) この部分は不要なので元に戻します 063 final ExecThread oet = getExecThread( queue.getThreadId() ); 064 oet.stackQueue( queue ); 065 } 066 067 /** 068 * キューを該当するスレッドにスタックする 069 * 070 * このメソッドでは、既に同じスレッドが存在するかどうかをチェックせずに必ず 071 * 新しいスレッドを生成し、キューを処理します。 072 * また、処理が完了した後、そのスレッドは、WAITすることなく終了します。 073 * 074 * @og.rev 5.1.6.0 (2010/05/01) 新規作成 075 * 076 * @param queue ExecQueueオブジェクト 077 */ 078 public static void insertQueueOnNewThread( final ExecQueue queue ) { 079 final ExecThread oet = new ExecThread( queue.getThreadId(), debug ); 080 oet.start(); 081 oet.stackQueue( queue ); 082 oet.finishAfterExec(); 083 } 084 085 /** 086 * 該当するスレッドIDを持つスレッドを取得します。 087 * スレッドプールに存在しない場合は、新規に作成されます。 088 * 089 * @og.rev 6.4.3.3 (2016/03/04) Map#compute で対応する。 090 * 091 * @param threadId スレッドID 092 * 093 * @return ExecThreadスレッド 094 */ 095 private static ExecThread getExecThread( final String threadId ) { 096 // Map#compute : 戻り値は、新しい値。追加有り、置換有り、削除有り 097 return EXEC_POOL.compute( threadId, (id,oet) -> 098 oet == null || !oet.isAlive() ? ExecThread.startExecThread( id, debug ) : oet ); 099 } 100 101 /** 102 * 全てのスレッドを終了します。 103 * 104 * ※ REP21/result2.jsp で、使用。 105 * 106 * @og.rev 6.4.3.3 (2016/03/04) Map#forEach で対応する。 107 */ 108 public static void finishAllThreads() { 109 EXEC_POOL.forEach( (id,oet) -> oet.finish() ); 110 System.out.println( "[INFO]ALL THREADS FINISHED" ); 111 } 112 113 /** 114 * 指定のスレッドを終了します。 115 * 116 * ※ REP21/entry.jsp で、使用。 117 * 118 * @param threadId スレッドID 119 */ 120 public static void finishThread( final String threadId ) { 121 final ExecThread oet = EXEC_POOL.remove( threadId ); 122 // Map上には null はないが、キーが合わない場合は、null が戻る。 123 if( oet != null ) { 124 oet.finish(); 125 System.out.println( "[INFO]THREAD CREATED:THREAD-ID=" + threadId ); 126 } 127 } 128 129 /** 130 * スレッド情報のマップを返します。 131 * 132 * ※ REP21/result2.jsp で、使用。 133 * 134 * @og.rev 6.4.3.1 (2016/02/12) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。 135 * @og.rev 6.4.3.3 (2016/03/04) 戻すMapが、not null制限つきであることを示すため、ConcurrentMap に置き換えます。 136 * @og.rev 6.4.3.3 (2016/03/04) Map#forEach で対応する。 137 * 138 * @return スレッド情報のマップ 139 */ 140 public static ConcurrentMap<String, String> getThreadInfo() { 141 final ConcurrentMap<String, String> infoMap = new ConcurrentHashMap<>(); 142 143 EXEC_POOL.forEach( (id,oet) -> infoMap.put( id,oet.toString() ) ); 144 145 return infoMap; 146 } 147 148 /** 149 * デバッグフラグの設定。 150 * 151 * @og.rev 4.3.0.0 (2008/07/15) デバッグ追加 152 * 153 * @param flag デバッグフラグ [true:デバッグ/false:通常] 154 */ 155 public static void setDebug ( final boolean flag ){ 156 debug = flag; 157 } 158}