- PR -

[JOTM]Tomcatのシャットダウンをしてもスレッドが残る問題について

1
投稿者投稿内容
oki
ベテラン
会議室デビュー日: 2004/12/18
投稿数: 55
投稿日時: 2006-12-14 14:39
お世話になります。

WindowsXP
Java 1.5.0_07
Tomcat 5.5.17
JOTM 2.0.10
Ecplise 3.1.1
Oracle 10g

上記の環境でTomcatをシャットダウンすると
JotmBatch、JotmClock、Timer-0のスレッドが残ってしまいます。

Tomcat自体は停止しているようですが
なぜ、上記のスレッドだけ停止されないのか原因がよく分かりません。

RedhatES環境でも同様の事象が発生しました。

Tomcatのログにはこれといったエラーがでていません。

回避方法をご存知の方おられましたら、ご教授お願いできますでしょうか?

[context.xml]
<Resource name="jdbc/oracle"
auth="Container"
type="javax.sql.DataSource"
factory="org.objectweb.jndi.DataSourceFactory"
driverClassName="oracle.jdbc.driver.OracleDriver"
username="user"
password="password"
url="jdbc:oracle:oci:@oracledb:1521:orcl"
max="50"
min="10"/>

<Resource name="UserTransaction" auth="Container"
type="javax.transaction.UserTransaction"
factory="org.objectweb.jotm.UserTransactionFactory"
jotm.timeout="60"/>

[carol.properties]
carol.rmi.activated = lmi
carol.jndi.start = false
carol.ns.start = false

よろしくお願い致します。

以上
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2006-12-14 14:42
スレッドが daemon に設定されていないからではないでしょうか。
daemon になっているかどうかはスレッドダンプをとれば確認できます。
oki
ベテラン
会議室デビュー日: 2004/12/18
投稿数: 55
投稿日時: 2006-12-14 23:52
お世話になります。

スレッドダンプでの確認はまだしておりませんが
JOTMのソースを解析したところdaemonの設定は行っているようです。

下記にソースの抜粋を掲載しますが
TimerMangerのコンストラクタでsetDaemon(true)を
行っているので問題ないように見ます。

誰かがTimerManagerのstop()を呼ばないといけないと
思うのですが、呼んでいる所が見つかりません。

ご教授お願いいたします。

------------------------------------------
コード:
package org.objectweb.jotm;
import java.util.Vector;
class Clock extends Thread {
    private TimerManager tmgr;
    public Clock(TimerManager tmgr) {
        super("JotmClock");
        if (TraceTm.jta.isDebugEnabled()) {
            TraceTm.jta.debug("Clock constructor");
        }
        this.tmgr = tmgr;
    }
    public void run() {
        tmgr.clock();
    }
}
class Batch extends Thread {
    private TimerManager tmgr;
    public Batch(TimerManager tmgr) {
        super("JotmBatch");
        if (TraceTm.jta.isDebugEnabled()) {
            TraceTm.jta.debug("Batch constructor");
        }
        this.tmgr = tmgr;
    }
    public void run() {
        tmgr.batch();
    }
}
public class TimerManager {
    // threads managing the service.
    private static Batch batchThread;
    private static Clock clockThread;
    // lists
    private Vector timerList = new Vector();
    private Vector expiredList = new Vector();
    private static TimerManager unique = null;
    private static boolean shuttingdown = false;
    private TimerManager() {
        // launch threads for timers
        batchThread = new Batch(this);
        batchThread.setDaemon(true); //←●●● daemonに設定 ●●●
        batchThread.start();
        clockThread = new Clock(this);
        clockThread.setDaemon(true); //←●●● daemonに設定 ●●●
        clockThread.start();
    }
    public static TimerManager getInstance() {
        if (unique == null)
            unique = new TimerManager();
        return unique;
    }

    /**
     * stop the service
     * @param force tell the manager NOT to wait for the timers to be completed
     */
    public static void stop(boolean force) {
        if (TraceTm.jta.isDebugEnabled()) {
            TraceTm.jta.debug("Stop TimerManager");
        }
        TimerManager tmgr = getInstance();
        shuttingdown = true;
        while (clockThread.isAlive() || batchThread.isAlive()) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                break;
            }
        }
        if (TraceTm.jta.isDebugEnabled()) {
            TraceTm.jta.debug("TimerManager has stopped");
        }
    }
    public static void stop() {
        stop(true);
    }
.......



山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2006-12-15 01:29
main スレッドが停止して、残りが全て daemon スレッドなら JVM は停止します。
「JotmBatch、JotmClock、Timer-0のスレッドが残っている」というのはスレッドダンプをとらずにどうやった確認したのでしょう?

まぁ、なにはともあれスレッドダンプです。誰がどこで何をしているのか分かりますから。

[ メッセージ編集済み 編集者: インギ 編集日時 2006-12-15 01:43 ]
oki
ベテラン
会議室デビュー日: 2004/12/18
投稿数: 55
投稿日時: 2006-12-15 10:45
お世話になっております。

Eclipseのデバッグビューで
残っているスレッドを確認しました。

スレッドダンプを収集しました。

よろしくお願い致します。

コード:

Full thread dump Java HotSpot(TM) Client VM (1.5.0_07-b03 mixed mode):

"DestroyJavaVM" prio=6 tid=0x0c568e70 nid=0xe7c waiting on condition [0x00000000..0x0007fab4]

"TP-Processor4" daemon prio=6 tid=0x0c574180 nid=0x4d0 in Object.wait() [0x0c75f000..0x0c75f9e8]
at java.lang.Object.wait(Native Method)
- waiting on <0x0345d8b8> (a org.apache.jk.common.ChannelSocket)
at java.lang.Object.wait(Unknown Source)
at org.apache.jk.common.ChannelSocket.accept(ChannelSocket.java:287)
- locked <0x0345d8b8> (a org.apache.jk.common.ChannelSocket)
at org.apache.jk.common.ChannelSocket.acceptConnections(ChannelSocket.java:647)
at org.apache.jk.common.ChannelSocket$SocketAcceptor.runIt(ChannelSocket.java:857)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
at java.lang.Thread.run(Unknown Source)

"http-80-Processor24" daemon prio=6 tid=0x0091d080 nid=0xf48 waiting on condition [0x0c4df000..0x0c4dfce8]
at java.lang.Thread.sleep(Native Method)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:61)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
at java.lang.Thread.run(Unknown Source)

"JotmClock" daemon prio=6 tid=0x008cbb30 nid=0x320 waiting on condition [0x0be5f000..0x0be5f9e8]
at java.lang.Thread.sleep(Native Method)
at org.objectweb.jotm.TimerManager.clock(TimerManager.java:169)
at org.objectweb.jotm.Clock.run(TimerManager.java:65)

"JotmBatch" daemon prio=6 tid=0x008cd0b0 nid=0xc08 in Object.wait() [0x0be1f000..0x0be1fa68]
at java.lang.Object.wait(Native Method)
- waiting on <0x032e81b0> (a java.util.Vector)
at java.lang.Object.wait(Unknown Source)
at org.objectweb.jotm.TimerManager.batch(TimerManager.java:221)
- locked <0x032e81b0> (a java.util.Vector)
at org.objectweb.jotm.Batch.run(TimerManager.java:87)

"GC Daemon" daemon prio=2 tid=0x008c9110 nid=0xc6c in Object.wait() [0x0bddf000..0x0bddfae8]
at java.lang.Object.wait(Native Method)
- waiting on <0x032db5a8> (a sun.misc.GC$LatencyLock)
at sun.misc.GC$Daemon.run(Unknown Source)
- locked <0x032db5a8> (a sun.misc.GC$LatencyLock)

"RMI Reaper" prio=6 tid=0x008c9e70 nid=0x2b0 in Object.wait() [0x0bd9f000..0x0bd9fb68]
at java.lang.Object.wait(Native Method)
- waiting on <0x032db5b0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(Unknown Source)
- locked <0x032db5b0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(Unknown Source)
at sun.rmi.transport.ObjectTable$Reaper.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

"Timer-0" daemon prio=6 tid=0x008c8970 nid=0xc58 in Object.wait() [0x0bd5f000..0x0bd5fbe8]
at java.lang.Object.wait(Native Method)
- waiting on <0x032db5d8> (a java.util.TaskQueue)
at java.lang.Object.wait(Unknown Source)
at java.util.TimerThread.mainLoop(Unknown Source)
- locked <0x032db5d8> (a java.util.TaskQueue)
at java.util.TimerThread.run(Unknown Source)

"RMI TCP Accept-0" daemon prio=6 tid=0x0087a570 nid=0xbdc runnable [0x0bd1f000..0x0bd1fc68]
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.PlainSocketImpl.accept(Unknown Source)
- locked <0x032db630> (a java.net.SocksSocketImpl)
at java.net.ServerSocket.implAccept(Unknown Source)
at java.net.ServerSocket.accept(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

"Low Memory Detector" daemon prio=6 tid=0x0083d630 nid=0x3b4 runnable [0x00000000..0x00000000]

"CompilerThread0" daemon prio=10 tid=0x0083b410 nid=0xcbc waiting on condition [0x00000000..0x0ae4f74c]

"Signal Dispatcher" daemon prio=10 tid=0x00839ac0 nid=0x138 waiting on condition [0x00000000..0x00000000]

"JDWP Command Reader" daemon prio=6 tid=0x00838cc0 nid=0x990 runnable [0x00000000..0x00000000]

"JDWP Event Helper Thread" daemon prio=6 tid=0x00836330 nid=0xb98 runnable [0x00000000..0x00000000]

"JDWP Transport Listener: dt_socket" daemon prio=6 tid=0x00835dd0 nid=0x870 runnable [0x00000000..0x0ad4f970]

"Finalizer" daemon prio=8 tid=0x0082d5d0 nid=0x42c in Object.wait() [0x0ac8f000..0x0ac8fc68]
at java.lang.Object.wait(Native Method)
- waiting on <0x030c8b28> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(Unknown Source)
- locked <0x030c8b28> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(Unknown Source)
at java.lang.ref.Finalizer$FinalizerThread.run(Unknown Source)

"Reference Handler" daemon prio=10 tid=0x0082c370 nid=0xe8c in Object.wait() [0x0ac4f000..0x0ac4fce8]
at java.lang.Object.wait(Native Method)
- waiting on <0x030c8b48> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Unknown Source)
at java.lang.ref.Reference$ReferenceHandler.run(Unknown Source)
- locked <0x030c8b48> (a java.lang.ref.Reference$Lock)

"VM Thread" prio=10 tid=0x0082b660 nid=0x87c runnable

"VM Periodic Task Thread" prio=10 tid=0x00840860 nid=0x6c0 waiting on condition





[ メッセージ編集済み 編集者: oki 編集日時 2006-12-15 10:50 ]
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2006-12-15 11:26
なるほど。デバッガでもスレッド確認できましたね! Eclipse には明るくないんですが、daemon かどうかは表示されないんでしょうか?

>よろしくお願い致します。
えーっと、何をお願いされているのでしょうか?
当初推測した通りdaemon じゃないスレッドが残っていますね。

お願いする前にまず調べるクセを付けると何かとためになります!

[ メッセージ編集済み 編集者: インギ 編集日時 2006-12-15 14:13 ]
1

スキルアップ/キャリアアップ(JOB@IT)