-title: Java PathFinder を使った Thread の検証 複数のJava の Thread が共有している文字列 String を調べて、 Thread の実行の様子を調べよう。 interlave Server.stringWork() を実行する。 何回か実行して見て、動作が異なるかどうかを調べよう。 --PathFinder による実行 Java PathFinder は Docker を使う方が良い。 Docker/JavaPathFinder/ Java PathFinder http://javapathfinder.sourceforge.net/ をinstallして実行しよう。 --Java 8 を使用する 残念ながら PathFinder は現在は Java 9 では動かない。以下の関数をzsh( ~/.zshrc )に組み込む。 function java_home { export JAVA_HOME=`/usr/libexec/java_home $@` echo "JAVA_HOME:" $JAVA_HOME echo "java -version:" java -version } これを有効にするには、 . ~/.zshrc とする。 zsh から、 java_home -v 1.8 で、そのzshから java 8 が使えるようになります。 --comment-begin: (naha:/net/open を共有して、 /Volume/naha.ie.u-ryukyu.ac.jp/JAVA/jpf/bin/jpf で実行しても良い。) --comment-end: 文字列の結合の結果がさまざまになるはずである。これは、Thread が interleaving (混ぜこぜ)に実行されることを示している。PathFinder はすべての可能な結果を示している。 Thread を三つに増やした場合は、どんな文字列が生成されるか。 実際に PathFinderを動作させて、生成された文字列と比較してみよ。 jpf のscript は、 JPF_HOME=/Users/kono/src/public/jpf-core と言うように、絶対パスで JPF_HOME を指定する方が便利。 jpf +classpath=. threadTest.TestThread というように実行します。threadTest/TestThread.java をcompileした threadTest/TestThread.class がないとだめ。 gradle project なら、top level から jpf +classpath=build/classes/java/main threadTest.TestThread --実行結果の説明 実行例の一つをUMLのシーケン図に示せ。 Thread が三つの場合の interleave の例題の synchronized を取って、生成される文字列を すべて示せ。 --synchornization がない場合 ThreadTest の例題で、 work() メソッドが直列可能でない実行している場合の文字列を一つ 示し、それが、どのような実行によって、生成されたかを UML の シーケンス図で記述せよ。 --assert ThreadTest の例題で、 Server.work() メソッドが 直列可能である条件を Java のassert を用いて記述し、 Thread が三つの場合に、 (1) synchronized を付けた場合に、assert が valid であること (2) synchronized がない場合に、assert の否定が satisfiable であること を PathFinder によって確認した結果を示せ。 AtomicInteger を使って、ThreadTestの例題(atomicWork)が正しく動くことを jpf で確認せよ。 ---example +leo+kono ~/src/public/jpf-core/bin/jpf +classpath=. threadTest.TestThread JavaPathfinder core system v8.0 (rev 32) - (C) 2005-2014 United States Government. All rights reserved. ====================================================== system under test threadTest.TestThread.main() ====================================================== search started: 1/8/19 1:38 PM ====================================================== results no errors detected ====================================================== statistics elapsed time: 00:00:00 states: new=773,visited=1301,backtracked=2074,end=4 search: maxDepth=20,constraints=0 choice generators: thread=773 (signal=0,lock=156,sharedRef=335,threadApi=25,reschedule=257), data=0 heap: new=395,released=107,maxLive=384,gcCycles=1517 instructions: 12688 max memory: 245MB loaded code: classes=65,methods=1514 ====================================================== search finished: 1/8/19 1:38 PM +leo+kono cat ~/src/public/jpf-core/bin/jpf #!/bin/bash # # unix shell script to run jpf # # JPF_HOME=`dirname "$0"`/.. JPF_HOME=$HOME/src/public/jpf-core if test -z "$JVM_FLAGS"; then JVM_FLAGS="-Xmx2048m -ea" fi /usr/libexec/java_home -v 1.8.0_152 --exec java -jar "$JPF_HOME/build/RunJPF.jar" "$@" #java $JVM_FLAGS -jar "$JPF_HOME/build/RunJPF.jar" "$@"