NetBeans

Java SE 9 の予習 その4

Java NetBeans

Java SE 9 の予習 その4です。

前回のエントリーの続きでおそらく今回も必要とされない無駄なお遊びとなります。

今回は JShell API を利用してアプリケーション内でスニペットの評価や実行を試してみます。

なお、今回のエントリーには 「Java SE 9のProject Kulla、JShellの動作とJShell API (3/4)(JShell API)」の記事を参考にさせていただきました。

ほとんどプログラムは丸写し状態になっていますので元記事をまず読んで理解してこのお遊びプログラムを堪能していただければ幸いです。

下記プログラムは普通に19行目のコンストラクタ内で JShell.create() メソッドによりオブジェクトを生成します。

1

スニペットの評価実行は29行目の eval(String snipetSource) メソッドでおこなわれます。(折り畳んでいるので隠れてます。)

( 最後にいろいろゴニョゴニョ遊んだコードを載せますので行番号はずれてしまいますが参考にしてくださいませ。)

List<SnippetEvent> eval(String snipetSource) メソッドで SnippetEvent オブジェクトを取得します。

JavaDoc では 戻り値:この評価によって直接的または間接的に発生したイベントのリスト となっています。

つまり、ステータスや値です。

種類は、jdk.​jshell.​Snippet クラスの public Kind kind() メソッドで取得します。

戻り値である jdk.jshell.Snippet.Kind は jdk.​jshell.​Snippet のサブクラスを示します。

jdk.jshell.Snippet.Kind は jdk.​jshell.​Snippet クラスの public static enum Kind extends Enum<Kind> となっています。

つまり種類は jdk.​jshell.​Snippet クラスのイミュータブルプロパティです。

jdk.​jshell.​Snippetクラスには 種類を補足するための  public SubKind subKind() メソッドも用意されています。

これは jdk.​jshell.​Snippet クラスの  public static enum SubKind extends Enum<SubKind> を返します。

これはユーザーへのフィードバックに役立ちます。

これは種類の詳細な情報を取得するのに利用されます。

ステータスの取得には jdk.​jshell.​SnippetEvent クラスの public Status status() メソッドを使用します。

戻り値は jdk.​jshell.​Snippet クラスの public static enum Status extends Enum<Status> です。

これは JShell ステート内の動的プロパティです。

したがって JShell クエリで取得されます。

ステータスには次の7つの状態があります。

DROPPED:スニペットは、JShell.drop(Snippet)への明示的な呼び出しのために非アクティブです。

NONEXISTENT:スニペットはまだ存在しないため、非アクティブです。

OVERWRITTEN : 新しいスニペットに置き換えられているため、このスニペットは無効です。

RECOVERABLE_DEFINED:スニペットは、(現在のJShell状態のコンテキストで)回復可能な未解決の参照やその他の問題が本体内にある可能性のある宣言スニペットです。

RECOVERABLE_NOT_DEFINED:スニペットは、(現在のJShell状態のコンテキストで)回復可能な未解決の参照やその他の問題がある可能性のある宣言スニペットです。

REJECTED:スニペットは、初期評価時にコンパイルに失敗し、JShell状態のさらなる変更で有効になることができないため、非アクティブです。

VALID:スニペットは有効なスニペット(現在のJShell状態のコンテキスト内)です。

このプログラムではステータスが VALID でなければ jdk.​jshell.​JShell クラスの public Stream<Diag> diagnostics(Snippet snippet) メソッドでスニペットの最新評価の診断を取得します。

そして jdk.​jshell.​Diag クラスの public abstract String getMessage(Locale locale) メソッドで指定されたロケールのローカライズされたメッセージを返します。

実際のメッセージは実装依存です。 ロケールがnullの場合、デフォルトのロケールを使用します。

値の取得には、jdk.​jshell.​SnippetEvent クラスの public String value() メソッドを使います。

戻り値は成功した実行の結果値。

実行されなかった場合、または例外がスローされた場合、値はnullです。

以上、だいたいこんな感じで JShell API を楽しんでいきたいと思います。

動かすスニペットは例の「よく見かけるネタ IntegerCache 問題」です。

これだけだとさみしいので FunctionalInterface を利用した挨拶プログラムも JShell API で動かしてみましょう。

非常にシンプルなスニペットの実行となります。

Import statement、FunctionalInterface、などのステータス、値、種類などの情報を正確に取得できれば OK です。

では、このプログラムの実行結果を見てみましょう。

FunctionalInterface は、ただの Interface として識別されるようです。

IntegerCache 問題 もちゃんと false となっています。

3

これだと普通すぎて面白くないですよね。

日本ではもうすぐ Java SE 9 がリリースされようという時代に End Of Life となった Java SE 7 でプロフラムを組まなければいけない

涙無くしては語れない非常に過酷な環境に置かれているプログラマが多く存在するらしい。

そこでそういう可愛そうなプログラマのためにコンパイラオプションを JDK7 にし、

IntegerCache 問題で遊ぶために JVM オプションに -XX:AutoBoxCacheMax=128 を設定して実行してみます。

JShell オブジェクトの生成を JShell.create() メソッドから JShell.builder() メソッドに変更します。

4

5

コンパイラオプションの設定は

jdk.​jshell.​JShell.​Builder クラスの public Builder compilerOptions(String… options) メソッドと使い設定します。

可変長引数の使い方が独特で思いっきりドツボにはまったのは内緒です。

JVM オプションの設定は

jdk.​jshell.​JShell.​Builder クラスの public Builder remoteVMOptions(String… options) メソッドを使い設定します。

後は入出力の設定です。

これらは連鎖初期化で使用するため Builderインスタンスを返します。

最後に jdk.​jshell.​JShell.​Builder クラスの public JShell build() メソッドで JShell ステートエンジンを構築します。

これはすべてのJShell機能のエントリーポイントです。

これにより、実行のためのリモートプロセスが作成されます。

それではコンパイラオプションと JVM オプションが正しく機能するかプログラムを走らせてみましょう。

6

うわぁぁ!!

正しく期待通りの動作となったが何故か目から涙がこぼれそうに・・・

IntegerCache 問題の実行結果も true となり正しく JVM オプションが設定されたようです。

これだけで天の邪鬼な私のお遊びは終了です。

ここから先は思い込みでサプライズさせてもらったお話しです。

先のプログラムにコンパイラオプションと JVM オプションを設定しない元の状態に戻して下記スニペットの実行コードを追加してみました。

JShell では import 文を必要としないパッケージが何故か存在します。

java.util.Arrays もその一つだから無事にプログラムは実行されるだろうと思っていました。

7

((((;゜Д゜)))))))  なんと! ERROR! EXPRESSION [ シンボルを見つけられません・・・ ]

JShell API を利用する場合はおもてなしは無しなのか!?

8

しかたないから import 文を追記してみた。

9

今度は期待通りの動作で実行された。

10

ついでだから enum も試してみた。

11

ちゃんと enum 認識していた。

12

実は Linux 環境の NetBeans IDE だからちゃんと日本語対応されているのですが

Windows 環境だと日本語は文字化けしてしまいます。

13

セレブデベロッパーご愛用の IntelliJ IDEA (2017.2 EAP)でも Windows環境での JShellAPI で日本語は文字化けしてしまう。

これは Java SE 9 リリースまでに修正されるのだろうか?

14

ちなみに Windows のコマンドプロンプトからの実行は文字化けしません。

15

以上、JShell API を無駄に使って遊んでみたエントリーでした。

お終い!

おっと!JShell API と戯れた記念コードを載せておきますね。

実行結果は次のようになります。

run:
import java.time.LocalTime;
<< Single-Type-Import Declaration. >>
@FunctionalInterface
interface Greeting<T, R> {
R apply(T time, R message);

        default void sayGreeting(String greeting) {
            greeting(greeting);
        }

        private void greeting(String greeting) {
            System.out.println(greeting + ” from JShellAPI.”);
        };
}
<< Created Interface: Greeting >>
LocalTime now = LocalTime.now();
<< A variable declaration with an initializer expression. >>
now ==> 17:28:24.474604
int hour = now.getHour();
<< A variable declaration with an initializer expression. >>
hour ==> 17
Greeting<Integer, String> greeting
                = (time, message) -> 4 <= time && time < 11 ? “Good morning!”
                        : 11 <= time && time < 18 ? “Good afternoon!”
                                : “Good evening!”;
<< A variable declaration with an initializer expression. >>
greeting ==> $Lambda$17/555826066@a67c67e
String message = null;
<< A variable declaration with an initializer expression. >>
message ==> null
greeting.sayGreeting(greeting.apply(hour, message));
Good afternoon! from JShellAPI.
<< Statement: Snippet:StatementKey#7-greeting.sayGreeting(greeting.apply(hour, message)); >>

(○・ω・)ノ———————————————————-)

Integer x = 128;
<< A variable declaration with an initializer expression. >>
x ==> 128
Integer y = 128;
<< A variable declaration with an initializer expression. >>
y ==> 128
void equivalenceTest(Integer x, Integer y) { System.out.println(x == y); }
<< Created Method: equivalenceTest(Integer,Integer) >>
equivalenceTest(x, y);
false
<< Statement: Snippet:StatementKey#11-equivalenceTest(x, y); >>
(○・ω・)ノ———————————————————-)

import java.util.Arrays;
<< Single-Type-Import Declaration. >>
String str;
<< A variable declaration without initializer. >>
str ==> null
str = “Java”;
<< An assignment expression. >>
str ==> “Java”
String[] elems = str.split(“”);
<< A variable declaration with an initializer expression. >>
elems ==> String[4] { “J”, “a”, “v”, “a” }
System.out.println(Arrays.toString(elems));
[J, a, v, a]
<< Statement: Snippet:StatementKey#16-System.out.println(Arrays.toString(elems)); >>
Arrays.stream(elems).forEach(System.out::println);
J
a
v
a
<< Statement: Snippet:StatementKey#17-Arrays.stream(elems).forEach(System.out::println); >>
(○・ω・)ノ———————————————————-)

public enum JavaPlusYou {

    Japanese(“あなたとJAVA,今すぐダウンロード”),
    English(“JAVA+YOU, DOWNLOAD TODAY!”);

    private final String downloadNow;

    private JavaPlusYou(final String downloadNow) {
        this.downloadNow = downloadNow;
    }

    public String getDownloadNow() {
        return downloadNow;
    }

}
<< Created Enum: JavaPlusYou >>
for (JavaPlusYou jpy : JavaPlusYou.values()) {
            System.out.println(jpy + “: ” + jpy.getDownloadNow());
        }
Japanese: あなたとJAVA,今すぐダウンロード
English: JAVA+YOU, DOWNLOAD TODAY!
<< Statement: Snippet:StatementKey#19-for (JavaPlusYou jpy : JavaPlusYou.values()) {
            System.out.println(jpy + “: ” + jpy.getDownloadNow());
        } >>
(○・ω・)ノ———————————————————-)

System.out.println(System.getProperty(“java.vm.version”));
9-ea+169
<< Statement: Snippet:StatementKey#20-System.out.println(System.getProperty(“java.vm.version”)); >>
System.out.println(System.getProperty(“java.class.version”));
53.0
<< Statement: Snippet:StatementKey#21-System.out.println(System.getProperty(“java.class.version”)); >>
(○・ω・)ノ———————————————————-)

ビルド成功(合計時間: 4秒)

Hatena タグ: ,

食事する哲学者の問題(Dining Philosophers Problem) Semaphore で遊ぶ その2

Java NetBeans

食事する哲学者の問題(Dining Philosophers Problem)を J2SE5.0 で追加された java.util.concurrent.Semaphore を使ってプログラムを組んでみます。

Semaphore については前回のエントリーでざっくり説明し、シンプルなプログラムも紹介しています。

Semaphore で遊ぶ

それでは、食事する哲学者の問題(Dining Philosophers Problem)とは何か調べてみます。

WikiPedia によると、食事する哲学者の問題(Dining Philosophers Problem)とは、並列処理に関する問題を一般化した例である。古典的なマルチプロセスの同期(排他制御)問題である。とされています。

もともとは、1965年、エドガー・ダイクストラは5台のコンピュータが5台のテープ装置に競合アクセスするという同期問題を提示した。

間もなく、この問題はアントニー・ホーアによって「食事する哲学者の問題」に変形して語られることとなった。

どうして食事する哲学者にすり替わったかは置いといて・・・

【問題】

5人の哲学者が食事したり、考え事をしたりしている。

かれらの前には、真ん中にスパゲッティの入った大きなボールが置かれた丸い食卓がある。

その食卓には5枚の皿が置かれ、皿と皿の間にフォークが1本ずつ置かれている。

スパゲッティをボールから取って自分の皿によそうには2本のフォークを必要とし、哲学者は一度に1本のフォークしかテーブルから取ることができない。

(左右の手で同時に両側にある2本のフォークを取ることはできない、という意味。まずどちらかの側のフォークを取ってから、逆の側のフォークを取る。)

哲学者同士は決して会話をしない。

このため、5人が左のフォークを手にとって右のフォークが食卓に置かれるのを待つという危険なデッドロック状態が発生する可能性がある。

スパゲッティではないけどこういう状況ですね。

cake1

【解説】

本来、デッドロック問題の解説手段として使われた。このシステムがデッドロックに到るのは「満たされない要求の円環」が存在する場合である。

例えば、哲学者 P1 が哲学者 P2 の手にしているフォークを待っていて、P2 は哲学者 P3 のものを……といったように円環形に要求が連鎖する。

例えば、それぞれの哲学者が次のように振る舞うとする。

1.左のフォークが得られるまで思索して待ち、フォークを取り上げる。

2.右のフォークが得られるまで思索して待ち、フォークを取り上げる。

3.食事する。

4.右のフォークを置く。

5.左のフォークを置く。

6.最初にもどって繰り返す。

この解法は正しくない。

このやりかたではデッドロックが発生し、全哲学者が左のフォークを持ち、右のフォークが持てるようになるのを待つという状況が発生しうる。

その場合、右のフォークは決して得られない (>_<。)

今回はこの方法でデッドロックを起こさないように Semaphore を使ってリソースへのアクセスを制限し対処するプログラムを組んでみることにします。

これって少し考えてみれば食事をしている両隣の哲学者はフォークをとれない状況ができるので同時に食事出来る哲学者の最大数は5人の場合は二人となります。

つまり、使われるフォークの数は4本となります。

これを利用すれば比較的簡単に Semaphore を利用してプログラムを組むことができますね。

それではプログラムを組んでみることにしますが、素直に哲学者に登場していただくより綺麗な女性を食事にお誘いしました。

今回デッドロックを避けるために使う Semaphore はウェイターの役割をはたします。

つまり、スパゲッティを食べる権利( パーミット取得 )があることを許可してくれます。

綺麗な女性は左のフォーク、そして右のフォークと使うことができればスパゲッティを食べることができます。

ただし、隣の女性がフォークを使っていたら( ロックがかかっていたら )フォークがあくのを待たなければ( ロックが解放される )いけません。

ウエイターは綺麗な女性がスパゲッティを食べ終わり左右のフォークを置いたなら、

その綺麗な女性のスパゲッティを食べる権利( パーミット )を戻してもらい、

次に待機している綺麗な女性がいれば「どうぞ、お食べください」とスパゲッティを食べる権利( パーミット )を与えます。。

そして綺麗な女性はフォークが空いていれば手に取りスパゲッティを食べられます。

フォークが空いていなければ待ちます。

これの繰り返しです。

最大二人の綺麗な女性がスパゲッティを同時に食べることがこれで可能となります。

左右のフォークの使用状況( ロックの状態 )によりフォーク待ち時間が発生してしまいますがこれでデッドロックは解消されます。

きっと綺麗な女性達は美味しいスパゲッティをお腹いっぱい食べて満足してお帰りになられたでしょう。

これをプログラムにすると次のようになりました。

プログラムを実行させてデッドロックが発生せず動作するか確認します。

桐谷美玲 左のフォークをとりあげる思索した時間は、0秒7838E-5
北川景子 左のフォークをとりあげる思索した時間は、0秒8168E-5
桐谷美玲 右のフォークをとりあげる思索した時間は、0秒313E-6
桐谷美玲 1回目の食事
桐谷美玲 1回目食事終了
北川景子 右のフォークをとりあげる思索した時間は、1秒3359217400000001
北川景子 1回目の食事
剛力彩芽 左のフォークをとりあげる思索した時間は、0秒9820000000000003E-6
北川景子 1回目食事終了
剛力彩芽 右のフォークをとりあげる思索した時間は、1秒3721449000000001
剛力彩芽 1回目の食事
堀北真希 左のフォークをとりあげる思索した時間は、0秒9820000000000003E-6
堀北真希 右のフォークをとりあげる思索した時間は、0秒9820000000000003E-6
堀北真希 1回目の食事
剛力彩芽 1回目食事終了
堀北真希 1回目食事終了
新垣結衣 左のフォークをとりあげる思索した時間は、0秒375070565
桐谷美玲 左のフォークをとりあげる思索した時間は、0秒9820000000000003E-6
新垣結衣 右のフォークをとりあげる思索した時間は、0秒9820000000000003E-6
桐谷美玲 右のフォークをとりあげる思索した時間は、0秒652E-6
桐谷美玲 2回目の食事
新垣結衣 1回目の食事
新垣結衣 1回目食事終了
北川景子 左のフォークをとりあげる思索した時間は、0秒652E-6
桐谷美玲 2回目食事終了
北川景子 右のフォークをとりあげる思索した時間は、0秒08200188600000001
北川景子 2回目の食事
剛力彩芽 左のフォークをとりあげる思索した時間は、0秒652E-6
北川景子 2回目食事終了
剛力彩芽 右のフォークをとりあげる思索した時間は、0秒583391387
堀北真希 左のフォークをとりあげる思索した時間は、0秒9820000000000003E-6
堀北真希 右のフォークをとりあげる思索した時間は、0秒652E-6
堀北真希 2回目の食事
剛力彩芽 2回目の食事
堀北真希 2回目食事終了
新垣結衣 左のフォークをとりあげる思索した時間は、0秒652E-6
剛力彩芽 2回目食事終了
新垣結衣 右のフォークをとりあげる思索した時間は、0秒436658855
桐谷美玲 左のフォークをとりあげる思索した時間は、0秒652E-6
桐谷美玲 右のフォークをとりあげる思索した時間は、0秒652E-6
新垣結衣 2回目の食事
桐谷美玲 3回目の食事
新垣結衣 2回目食事終了
北川景子 左のフォークをとりあげる思索した時間は、0秒294E-6
桐谷美玲 3回目食事終了
北川景子 右のフォークをとりあげる思索した時間は、0秒23805942200000002
北川景子 3回目の食事
堀北真希 左のフォークをとりあげる思索した時間は、0秒6510000000000002E-6
堀北真希 右のフォークをとりあげる思索した時間は、0秒9820000000000003E-6
堀北真希 3回目の食事
北川景子 3回目食事終了
剛力彩芽 左のフォークをとりあげる思索した時間は、0秒312E-6
剛力彩芽 右のフォークをとりあげる思索した時間は、0秒6510000000000002E-6
剛力彩芽 3回目の食事
堀北真希 3回目食事終了
新垣結衣 左のフォークをとりあげる思索した時間は、0秒652E-6
剛力彩芽 3回目食事終了
新垣結衣 右のフォークをとりあげる思索した時間は、0秒18132323900000002
新垣結衣 3回目の食事
桐谷美玲 左のフォークをとりあげる思索した時間は、0秒652E-6
桐谷美玲 右のフォークをとりあげる思索した時間は、0秒9820000000000003E-6
桐谷美玲 4回目の食事
新垣結衣 3回目食事終了
北川景子 左のフォークをとりあげる思索した時間は、0秒9820000000000003E-6
桐谷美玲 4回目食事終了
北川景子 右のフォークをとりあげる思索した時間は、0秒39374600600000004
北川景子 4回目の食事
堀北真希 左のフォークをとりあげる思索した時間は、0秒652E-6
堀北真希 右のフォークをとりあげる思索した時間は、0秒312E-6
堀北真希 4回目の食事
堀北真希 4回目食事終了
剛力彩芽 左のフォークをとりあげる思索した時間は、0秒9640000000000005E-6
北川景子 4回目食事終了
剛力彩芽 右のフォークをとりあげる思索した時間は、0秒023616073
剛力彩芽 4回目の食事
新垣結衣 左のフォークをとりあげる思索した時間は、0秒6510000000000002E-6
剛力彩芽 4回目食事終了
新垣結衣 右のフォークをとりあげる思索した時間は、0秒7176410350000001
桐谷美玲 左のフォークをとりあげる思索した時間は、0秒312E-6
新垣結衣 4回目の食事
桐谷美玲 右のフォークをとりあげる思索した時間は、0秒9820000000000003E-6
桐谷美玲 5回目の食事
桐谷美玲 5回目食事終了
堀北真希 左のフォークをとりあげる思索した時間は、0秒9820000000000003E-6
新垣結衣 4回目食事終了
堀北真希 右のフォークをとりあげる思索した時間は、0秒718831517
堀北真希 5回目の食事
北川景子 左のフォークをとりあげる思索した時間は、0秒9820000000000003E-6
北川景子 右のフォークをとりあげる思索した時間は、0秒3543E-5
北川景子 5回目の食事
堀北真希 5回目食事終了
剛力彩芽 左のフォークをとりあげる思索した時間は、0秒6430000000000004E-6
北川景子 5回目食事終了
剛力彩芽 右のフォークをとりあげる思索した時間は、0秒140569047
剛力彩芽 5回目の食事
桐谷美玲 左のフォークをとりあげる思索した時間は、0秒981E-6
桐谷美玲 右のフォークをとりあげる思索した時間は、0秒9820000000000003E-6
桐谷美玲 6回目の食事
桐谷美玲 6回目食事終了
新垣結衣 左のフォークをとりあげる思索した時間は、0秒6420000000000003E-6
剛力彩芽 5回目食事終了
新垣結衣 右のフォークをとりあげる思索した時間は、0秒256017732
新垣結衣 5回目の食事
堀北真希 左のフォークをとりあげる思索した時間は、0秒9820000000000003E-6
新垣結衣 5回目食事終了
堀北真希 右のフォークをとりあげる思索した時間は、0秒908995176
堀北真希 6回目の食事
北川景子 左のフォークをとりあげる思索した時間は、0秒973E-6
北川景子 右のフォークをとりあげる思索した時間は、0秒313E-6
北川景子 6回目の食事
堀北真希 6回目食事終了
北川景子 6回目食事終了
桐谷美玲 左のフォークをとりあげる思索した時間は、0秒156232277
剛力彩芽 左のフォークをとりあげる思索した時間は、0秒3210000000000001E-6
桐谷美玲 右のフォークをとりあげる思索した時間は、0秒652E-6
桐谷美玲 7回目の食事
剛力彩芽 右のフォークをとりあげる思索した時間は、0秒9820000000000003E-6
剛力彩芽 6回目の食事
桐谷美玲 7回目食事終了
新垣結衣 左のフォークをとりあげる思索した時間は、0秒312E-6
剛力彩芽 6回目食事終了
新垣結衣 右のフォークをとりあげる思索した時間は、0秒200991297
新垣結衣 6回目の食事
堀北真希 左のフォークをとりあげる思索した時間は、0秒652E-6
新垣結衣 6回目食事終了
堀北真希 右のフォークをとりあげる思索した時間は、1秒3822943870000002
堀北真希 7回目の食事
北川景子 左のフォークをとりあげる思索した時間は、0秒9820000000000003E-6
北川景子 右のフォークをとりあげる思索した時間は、0秒3030000000000004E-6
北川景子 7回目の食事
堀北真希 7回目食事終了
北川景子 7回目食事終了
桐谷美玲 左のフォークをとりあげる思索した時間は、0秒089658099
桐谷美玲 右のフォークをとりあげる思索した時間は、0秒9820000000000003E-6
桐谷美玲 8回目の食事
剛力彩芽 左のフォークをとりあげる思索した時間は、0秒625000000000001E-6
剛力彩芽 右のフォークをとりあげる思索した時間は、0秒313E-6
剛力彩芽 7回目の食事
剛力彩芽 7回目食事終了
新垣結衣 左のフォークをとりあげる思索した時間は、0秒955E-6
新垣結衣 右のフォークをとりあげる思索した時間は、0秒652E-6
新垣結衣 7回目の食事
桐谷美玲 8回目食事終了
堀北真希 左のフォークをとりあげる思索した時間は、0秒3210000000000001E-6
新垣結衣 7回目食事終了
堀北真希 右のフォークをとりあげる思索した時間は、0秒8264462760000001
北川景子 左のフォークをとりあげる思索した時間は、0秒6510000000000002E-6
堀北真希 8回目の食事
北川景子 右のフォークをとりあげる思索した時間は、0秒3210000000000001E-6
北川景子 8回目の食事
堀北真希 8回目食事終了
剛力彩芽 左のフォークをとりあげる思索した時間は、0秒6420000000000003E-6
北川景子 8回目食事終了
剛力彩芽 右のフォークをとりあげる思索した時間は、0秒217371327
剛力彩芽 8回目の食事
桐谷美玲 左のフォークをとりあげる思索した時間は、0秒9820000000000003E-6
桐谷美玲 右のフォークをとりあげる思索した時間は、0秒312E-6
桐谷美玲 9回目の食事
剛力彩芽 8回目食事終了
新垣結衣 左のフォークをとりあげる思索した時間は、0秒9820000000000003E-6
新垣結衣 右のフォークをとりあげる思索した時間は、0秒6510000000000002E-6
新垣結衣 8回目の食事
桐谷美玲 9回目食事終了
堀北真希 左のフォークをとりあげる思索した時間は、0秒3210000000000001E-6
新垣結衣 8回目食事終了
堀北真希 右のフォークをとりあげる思索した時間は、1秒21894861600000004
北川景子 左のフォークをとりあげる思索した時間は、0秒9820000000000003E-6
堀北真希 9回目の食事
北川景子 右のフォークをとりあげる思索した時間は、0秒9820000000000003E-6
北川景子 9回目の食事
堀北真希 9回目食事終了
剛力彩芽 左のフォークをとりあげる思索した時間は、0秒652E-6
北川景子 9回目食事終了
剛力彩芽 右のフォークをとりあげる思索した時間は、0秒780406594
剛力彩芽 9回目の食事
桐谷美玲 左のフォークをとりあげる思索した時間は、0秒9820000000000003E-6
桐谷美玲 右のフォークをとりあげる思索した時間は、0秒294E-6
桐谷美玲 10回目の食事
剛力彩芽 9回目食事終了
新垣結衣 左のフォークをとりあげる思索した時間は、0秒973E-6
新垣結衣 右のフォークをとりあげる思索した時間は、0秒652E-6
新垣結衣 9回目の食事
桐谷美玲 10回目食事終了
堀北真希 左のフォークをとりあげる思索した時間は、0秒3210000000000001E-6
新垣結衣 9回目食事終了
堀北真希 右のフォークをとりあげる思索した時間は、0秒475458529
堀北真希 10回目の食事
北川景子 左のフォークをとりあげる思索した時間は、0秒9820000000000003E-6
北川景子 右のフォークをとりあげる思索した時間は、0秒312E-6
北川景子 10回目の食事
堀北真希 10回目食事終了
剛力彩芽 左のフォークをとりあげる思索した時間は、0秒652E-6
北川景子 10回目食事終了
剛力彩芽 右のフォークをとりあげる思索した時間は、0秒34860347900000005
新垣結衣 左のフォークをとりあげる思索した時間は、0秒652E-6
剛力彩芽 10回目の食事
剛力彩芽 10回目食事終了
新垣結衣 右のフォークをとりあげる思索した時間は、1秒0036094330000000507
新垣結衣 10回目の食事
新垣結衣 10回目食事終了

堀北真希 が 10回食事するのに要した時間は、28秒6504769030000013でした。
新垣結衣 が 10回食事するのに要した時間は、30秒9585105100000035でした。
剛力彩芽 が 10回食事するのに要した時間は、30秒0028747960000004014でした。
北川景子 が 10回食事するのに要した時間は、28秒998852129000003でした。
桐谷美玲 が 10回食事するのに要した時間は、27秒3586783140000023でした。

(○・ω・)ノ——– I eat delicious spaghetti and am stuffed. ——–(^_^)

ちゃんと動きました。(^_^)

このプログラムでは Semaphore インスタンス生成時のコンストラクタ引数に哲学者の人数を割り当てました。

また、公平性も設定しました。

パーミット数の設定は同時アクセスは 2 スレッドまでなので 2 と設定して、acquire()、release() とパーミット取得数とパーミット解放数を 1 してもいいでしょう。

今回は、パーミット数の設定を 5 , acquire(2)、release(2) とパーミット取得数とパーミット解放数を 2 としました。

同時アクセス可能なのが 2 スレッドで左右のフォークをロックするのでこの問題の鍵となるフォークの数を考慮にいれました。(あまり意味の無いこだわり)

final Semaphore semaphore = new Semaphore(PHILOSOPHERS_NUMBER, true);

NetBeans のプロファイラでスレッドの状態を確認してみましょう。

1

5 個の ForkJoinPool.commonPool-worker-29 とかのスレッドが最大で二つ同時アクセスされているのが確認できます。

スレッド終了後にフォークのロック解放待ちが無い場合はすぐに新たなスレッドが実行されているのも確認できます。

Semaphore って本当に便利ですね!

さて、ここでちょっとしたことを試してみよう。

Semaphore の公平性の設定をしなかったらどうなるのか?

final Semaphore semaphore = new Semaphore(PHILOSOPHERS_NUMBER); // 公平性無し

では、プログラムを実行させてみます。

剛力彩芽 左のフォークをとりあげる思索した時間は、0秒0810000000000002E-5
堀北真希 左のフォークをとりあげる思索した時間は、0秒0810000000000002E-5
剛力彩芽 右のフォークをとりあげる思索した時間は、0秒9820000000000003E-6
堀北真希 右のフォークをとりあげる思索した時間は、0秒9820000000000003E-6
剛力彩芽 1回目の食事
堀北真希 1回目の食事
堀北真希 1回目食事終了
堀北真希 左のフォークをとりあげる思索した時間は、0秒313E-6
堀北真希 右のフォークをとりあげる思索した時間は、0秒652E-6
堀北真希 2回目の食事
剛力彩芽 1回目食事終了
剛力彩芽 左のフォークをとりあげる思索した時間は、0秒312E-6
剛力彩芽 右のフォークをとりあげる思索した時間は、0秒652E-6
剛力彩芽 2回目の食事
堀北真希 2回目食事終了
堀北真希 左のフォークをとりあげる思索した時間は、0秒312E-6
堀北真希 右のフォークをとりあげる思索した時間は、0秒652E-6
堀北真希 3回目の食事
剛力彩芽 2回目食事終了
剛力彩芽 左のフォークをとりあげる思索した時間は、0秒910000000000001E-7
剛力彩芽 右のフォークをとりあげる思索した時間は、0秒3210000000000001E-6
剛力彩芽 3回目の食事
堀北真希 3回目食事終了
堀北真希 左のフォークをとりあげる思索した時間は、0秒3210000000000001E-6
堀北真希 右のフォークをとりあげる思索した時間は、0秒6510000000000002E-6
堀北真希 4回目の食事
剛力彩芽 3回目食事終了
剛力彩芽 左のフォークをとりあげる思索した時間は、0秒910000000000001E-7
剛力彩芽 右のフォークをとりあげる思索した時間は、0秒3210000000000001E-6
剛力彩芽 4回目の食事
堀北真希 4回目食事終了
堀北真希 左のフォークをとりあげる思索した時間は、0秒9820000000000003E-6
堀北真希 右のフォークをとりあげる思索した時間は、0秒652E-6
堀北真希 5回目の食事
剛力彩芽 4回目食事終了
剛力彩芽 左のフォークをとりあげる思索した時間は、0秒6420000000000003E-6
剛力彩芽 右のフォークをとりあげる思索した時間は、0秒6510000000000002E-6
剛力彩芽 5回目の食事
堀北真希 5回目食事終了
堀北真希 左のフォークをとりあげる思索した時間は、0秒312E-6
堀北真希 右のフォークをとりあげる思索した時間は、0秒3210000000000001E-6
堀北真希 6回目の食事
剛力彩芽 5回目食事終了
剛力彩芽 左のフォークをとりあげる思索した時間は、0秒910000000000001E-7
剛力彩芽 右のフォークをとりあげる思索した時間は、0秒652E-6
剛力彩芽 6回目の食事
剛力彩芽 6回目食事終了
剛力彩芽 左のフォークをとりあげる思索した時間は、0秒312E-6
剛力彩芽 右のフォークをとりあげる思索した時間は、0秒6510000000000002E-6
剛力彩芽 7回目の食事
堀北真希 6回目食事終了
堀北真希 左のフォークをとりあげる思索した時間は、0秒910000000000001E-7
堀北真希 右のフォークをとりあげる思索した時間は、0秒652E-6
堀北真希 7回目の食事
剛力彩芽 7回目食事終了
剛力彩芽 左のフォークをとりあげる思索した時間は、0秒6510000000000002E-6
剛力彩芽 右のフォークをとりあげる思索した時間は、0秒6510000000000002E-6
剛力彩芽 8回目の食事
堀北真希 7回目食事終了
堀北真希 左のフォークをとりあげる思索した時間は、0秒910000000000001E-7
堀北真希 右のフォークをとりあげる思索した時間は、0秒652E-6
堀北真希 8回目の食事
剛力彩芽 8回目食事終了
剛力彩芽 左のフォークをとりあげる思索した時間は、0秒3210000000000001E-6
剛力彩芽 右のフォークをとりあげる思索した時間は、0秒973E-6
剛力彩芽 9回目の食事
堀北真希 8回目食事終了
堀北真希 左のフォークをとりあげる思索した時間は、0秒6430000000000004E-6
堀北真希 右のフォークをとりあげる思索した時間は、0秒3210000000000001E-6
堀北真希 9回目の食事
剛力彩芽 9回目食事終了
剛力彩芽 左のフォークをとりあげる思索した時間は、0秒652E-6
剛力彩芽 右のフォークをとりあげる思索した時間は、0秒652E-6
剛力彩芽 10回目の食事
堀北真希 9回目食事終了
堀北真希 左のフォークをとりあげる思索した時間は、0秒3210000000000001E-6
堀北真希 右のフォークをとりあげる思索した時間は、0秒652E-6
堀北真希 10回目の食事
剛力彩芽 10回目食事終了
桐谷美玲 左のフォークをとりあげる思索した時間は、0秒312E-6
堀北真希 10回目食事終了
北川景子 左のフォークをとりあげる思索した時間は、0秒616E-6
桐谷美玲 右のフォークをとりあげる思索した時間は、0秒830071894
桐谷美玲 1回目の食事
桐谷美玲 1回目食事終了
北川景子 右のフォークをとりあげる思索した時間は、0秒888391644
北川景子 1回目の食事
北川景子 1回目食事終了
北川景子 左のフォークをとりあげる思索した時間は、0秒6420000000000003E-6
桐谷美玲 左のフォークをとりあげる思索した時間は、1秒44702734600000005
桐谷美玲 右のフォークをとりあげる思索した時間は、0秒652E-6
桐谷美玲 2回目の食事
桐谷美玲 2回目食事終了
北川景子 右のフォークをとりあげる思索した時間は、1秒2932113780000001
北川景子 2回目の食事
北川景子 2回目食事終了
北川景子 左のフォークをとりあげる思索した時間は、0秒3030000000000004E-6
桐谷美玲 左のフォークをとりあげる思索した時間は、0秒6195947270000001
桐谷美玲 右のフォークをとりあげる思索した時間は、0秒312E-6
桐谷美玲 3回目の食事
桐谷美玲 3回目食事終了
北川景子 右のフォークをとりあげる思索した時間は、1秒23741232
北川景子 3回目の食事
北川景子 3回目食事終了
北川景子 左のフォークをとりあげる思索した時間は、0秒6420000000000003E-6
桐谷美玲 左のフォークをとりあげる思索した時間は、1秒2788060170000002
桐谷美玲 右のフォークをとりあげる思索した時間は、0秒652E-6
桐谷美玲 4回目の食事
桐谷美玲 4回目食事終了
北川景子 右のフォークをとりあげる思索した時間は、0秒9319671190000001
北川景子 4回目の食事
北川景子 4回目食事終了
北川景子 左のフォークをとりあげる思索した時間は、0秒633E-6
桐谷美玲 左のフォークをとりあげる思索した時間は、0秒55758825
桐谷美玲 右のフォークをとりあげる思索した時間は、0秒3543E-5
桐谷美玲 5回目の食事
桐谷美玲 5回目食事終了
北川景子 右のフォークをとりあげる思索した時間は、0秒7469512070000001
北川景子 5回目の食事
北川景子 5回目食事終了
北川景子 左のフォークをとりあげる思索した時間は、0秒910000000000001E-7
桐谷美玲 左のフォークをとりあげる思索した時間は、1秒08432603500000013
桐谷美玲 右のフォークをとりあげる思索した時間は、0秒973E-6
桐谷美玲 6回目の食事
桐谷美玲 6回目食事終了
北川景子 右のフォークをとりあげる思索した時間は、0秒733817256
北川景子 6回目の食事
北川景子 6回目食事終了
北川景子 左のフォークをとりあげる思索した時間は、0秒9820000000000003E-6
桐谷美玲 左のフォークをとりあげる思索した時間は、1秒1698336330000001
桐谷美玲 右のフォークをとりあげる思索した時間は、0秒312E-6
桐谷美玲 7回目の食事
桐谷美玲 7回目食事終了
北川景子 右のフォークをとりあげる思索した時間は、1秒4533695360000001
北川景子 7回目の食事
北川景子 7回目食事終了
北川景子 左のフォークをとりあげる思索した時間は、0秒322E-6
桐谷美玲 左のフォークをとりあげる思索した時間は、0秒8525430700000001
桐谷美玲 右のフォークをとりあげる思索した時間は、0秒652E-6
桐谷美玲 8回目の食事
桐谷美玲 8回目食事終了
北川景子 右のフォークをとりあげる思索した時間は、0秒669598278
北川景子 8回目の食事
北川景子 8回目食事終了
北川景子 左のフォークをとりあげる思索した時間は、0秒9820000000000003E-6
桐谷美玲 左のフォークをとりあげる思索した時間は、1秒3454052980000002
桐谷美玲 右のフォークをとりあげる思索した時間は、0秒9820000000000003E-6
桐谷美玲 9回目の食事
桐谷美玲 9回目食事終了
北川景子 右のフォークをとりあげる思索した時間は、1秒25630280000000005
北川景子 9回目の食事
北川景子 9回目食事終了
北川景子 左のフォークをとりあげる思索した時間は、0秒652E-6
桐谷美玲 左のフォークをとりあげる思索した時間は、0秒598060677
桐谷美玲 右のフォークをとりあげる思索した時間は、0秒6510000000000002E-6
桐谷美玲 10回目の食事
桐谷美玲 10回目食事終了
北川景子 右のフォークをとりあげる思索した時間は、1秒09184714699999996
北川景子 10回目の食事
新垣結衣 左のフォークをとりあげる思索した時間は、0秒946E-6
新垣結衣 右のフォークをとりあげる思索した時間は、0秒312E-6
新垣結衣 1回目の食事
北川景子 10回目食事終了
新垣結衣 1回目食事終了
新垣結衣 左のフォークをとりあげる思索した時間は、0秒973E-6
新垣結衣 右のフォークをとりあげる思索した時間は、0秒6510000000000002E-6
新垣結衣 2回目の食事
新垣結衣 2回目食事終了
新垣結衣 左のフォークをとりあげる思索した時間は、0秒6430000000000004E-6
新垣結衣 右のフォークをとりあげる思索した時間は、0秒6510000000000002E-6
新垣結衣 3回目の食事
新垣結衣 3回目食事終了
新垣結衣 左のフォークをとりあげる思索した時間は、0秒312E-6
新垣結衣 右のフォークをとりあげる思索した時間は、0秒652E-6
新垣結衣 4回目の食事
新垣結衣 4回目食事終了
新垣結衣 左のフォークをとりあげる思索した時間は、0秒322E-6
新垣結衣 右のフォークをとりあげる思索した時間は、0秒6510000000000002E-6
新垣結衣 5回目の食事
新垣結衣 5回目食事終了
新垣結衣 左のフォークをとりあげる思索した時間は、0秒024E-5
新垣結衣 右のフォークをとりあげる思索した時間は、0秒6510000000000002E-6
新垣結衣 6回目の食事
新垣結衣 6回目食事終了
新垣結衣 左のフォークをとりあげる思索した時間は、0秒973E-6
新垣結衣 右のフォークをとりあげる思索した時間は、0秒3210000000000001E-6
新垣結衣 7回目の食事
新垣結衣 7回目食事終了
新垣結衣 左のフォークをとりあげる思索した時間は、0秒6430000000000004E-6
新垣結衣 右のフォークをとりあげる思索した時間は、0秒9820000000000003E-6
新垣結衣 8回目の食事
新垣結衣 8回目食事終了
新垣結衣 左のフォークをとりあげる思索した時間は、0秒652E-6
新垣結衣 右のフォークをとりあげる思索した時間は、0秒3210000000000001E-6
新垣結衣 9回目の食事
新垣結衣 9回目食事終了
新垣結衣 左のフォークをとりあげる思索した時間は、0秒910000000000001E-7
新垣結衣 右のフォークをとりあげる思索した時間は、0秒6510000000000002E-6
新垣結衣 10回目の食事
新垣結衣 10回目食事終了

堀北真希 が 10回食事するのに要した時間は、10秒9469584730000005でした。
新垣結衣 が 10回食事するのに要した時間は、40秒20581136300000225でした。
剛力彩芽 が 10回食事するのに要した時間は、10秒11629695400000095でした。
北川景子 が 10回食事するのに要した時間は、31秒21609595200000342でした。
桐谷美玲 が 10回食事するのに要した時間は、30秒20136357100000168でした。

(○・ω・)ノ——– I eat delicious spaghetti and am stuffed. ——–(^_^)

うわぁぁぁ・・・ 思いっきり不公平じゃないですか!

NetBeans のプロファイラでスレッドの状態を確認してみます。

2

今回のようなフォークのロック解放待ちがあるような場合はまずいような・・・

こんなとこもあるよね。

3

プログラムの処理時間が大幅に増えてます。

公平性の設定はよく考えないと思わぬ結果をもたらすかもしれませんね。

CompletableFuture を使えば楽に並行処理を記述できるし、Java って世に出たときはマルチスレッド対応だぜ!って誇らしげに売りにしていた。

あれから20年、確実に進化しています。

どんどん進化していく並行処理を日本語で優しく解説しているサイトはあまり無いのが残念です。

便利なものほど正しく使わないと痛い目をみますからね。

もっと正しい知識を優しい日本語の解説で入手したい今日この頃です。

今月の私は健康診断でコレステロールと中性脂肪の値が高いと指摘されたにもかかわらずこういった美味しいケーキをたくさん食べてしまいました。

c4

c3

c2

c5

美味しさそのままで中性脂肪とコレステロールの値をさげるケーキって無いものか。

お終い!

Hatena タグ:

Semaphore で遊ぶ

Java NetBeans

早いもので今日は五月五日 こどもの日です。

祝日法2条によれば、「こどもの人格を重んじ、こどもの幸福をはかるとともに、母に感謝する」となっています。

5月5日は古来から端午の節句として日本では男子の健やかな成長を祈願し各種の行事を行う風習があります。

ということで、私も男子の健やかな成長を祈願するプログラムを組むことにしました。

今さらですが、J2SE5.0 で追加された java.util.concurrent.Semaphore をつかってふざけた 夢のようなプログラム組みました。

男子の健やかな成長には素敵な女性との出会いは必要不可欠です。

だから4人の素敵な女性にデートに誘われると言う内容です。

しかし、体は一つしかありませんので一度に4人では収集付かなくなります。

そこで恭平さんにヘルプをお願いしました。(^_^;)

これでも、素敵な女性4人に対して男子は二人です。

これでなんとかするために Semaphore を使って二組のカップルまでがデートに出かけられるとします。

残りの二人の女性は先に出かけた二組のカップルのどちらか片方が帰ってきたらデートに出かけるという設定です。

つまり、男子二人というリソースに同時アクセス出来るのは素敵な女性スレッド二つまでということになります。

それが Semaphore を使えば実現できてしまうのです。

Semaphore はざっくり説明するとリソースに対するアクセスが可能か不可能かのいずれかの値をとる Binary Semaphore と

アクセス可能なリソース数を任意に設定することが出来る Counting Semaphore があります。

Java で採用された Semaphore は Counting Semaphore にあたります。

有限リソースに対して並行アクセス可能なスレッド数を自由に設定できます。

今回組むプログラムにうってつけの優れものとなっています。(^_^)

17 行目で Semaphore を生成しています。

コンストラクタの引数はパーミット数と公平性を設定します。

今回のプログラムではパーミット数はリソース数と同じ 2 となっています。

公平性は API ドキュメントを見ると今回のプログラムの場合は優しい私はパフォーマンスより平等性を重視して true と設定しました。

ちなみに API ドキュメントによると

このクラスのコンストラクタは、オプションで公平性パラメータを受け入れます。
falseに設定すると、このクラスはスレッドがパーミットを取得する順序について保証しません。
特に、バージ(barging)が許可されています。
つまり、acquire()を呼び出すスレッドに、待機していたスレッドより先にパーミットを割り当てることができます。
論理的には、新しいスレッドが、待機中のスレッドのキューの先頭に配置されます。
公平性がtrueに設定されると、セマフォは、acquireメソッドのいずれかを呼び出すスレッドが、これらのメソッドの呼出しが処理された順序(先入れ先出し、FIFO)でパーミットを取得するように選択されることを保証します。
FIFO順序付けは、必然的にこれらのメソッド内の特定の内部実行ポイントに適用されます。
そのため、あるスレッドが別のスレッドより前にacquireを呼び出しても、そのスレッドよりあとに順序付けポイントに到達する可能性があります。
また、メソッドからの復帰時も同様です。また、時間指定のないtryAcquireメソッドは公平性の設定に従いませんが、利用可能なパーミットをすべて取得することにも注意してください。

となっています。

実は今回のプログラムではこの公平性の設定の違いというのは解りにくいのですが

食事する哲学者の問題Dining Philosophers Problem)を Semaphore を使った簡易的なプログラムを組んでみるとよく解ります。

次に Semaphore からパーミットを取得するために acquire() メソッドを使います。

このプログラムでは 23 行目で使っています。

public void acquire() throws InterruptedException は API ドキュメントによると次のようになっています。

このセマフォからパーミットを取得します。パーミットが利用可能になるか、またはスレッドが割り込みされるまでブロックします。
パーミットが利用可能な場合はパーミットを取得してすぐに復帰するため、利用可能なパーミットの数は1つずつ減ります。

パーミットが利用可能でない場合、現在のスレッドはスレッドのスケジューリングに関して無効になり、次の2つのいずれかが起きるまで待機します。
•ほかのスレッドがこのセマフォに対してrelease()メソッドを呼び出し、現在のスレッドが次にパーミットを割り当てられるスレッドになる。
•ほかのスレッドが現在のスレッドに割り込みを行う。

現在のスレッドで、
•このメソッドへのエントリ上で設定された割込みステータスが保持されるか、
•パーミットの待機中に割り込みが発生した場合、
InterruptedExceptionがスローされ、現在のスレッドの割込みステータスがクリアされます。例外:InterruptedException – 現在のスレッドで割込みが発生した場合

これとは別に引数で取得するパーミット数を設定できるメソッドもあります。

次は取得したパーミットを解放する release() メソッドを調べてみます。

33 行目で使っています。

デートが終了したらパーミットを保持する必要はないので解放します。

public void release() は API ドキュメントによると次のように書かれています。

パーミットを解放し、セマフォに戻します。
パーミットを解放すると、利用可能なパーミットの数が1つずつ増えます。
いくつかのスレッドがパーミットを取得しようと試みている場合は、その中の1つのスレッドが選択され、解放されたばかりのパーミットが与えられます。
そのスレッドは、スレッドのスケジューリングに関して(ふたたび)有効になります。

パーミットを解放するスレッドは、acquire()の呼出しでそのパーミットを取得している必要はありません。
セマフォの適切な使用法は、アプリケーションでのプログラミング規約で確立されます。

たったこれだけでリソースにアクセスできる並行スレッド数を制限できてしまうんですねぇ・・・

このプログラムの実行結果は次のようになります。

待っているのは、堀北真希
待っているのは、北川景子
待っているのは、新垣結衣
待っているのは、剛力彩芽
今からデートに行くのは、北川景子
今からデートに行くのは、堀北真希
北川景子 は ゆっち とデートに行きました。
堀北真希 は 恭平 とデートに行きました。
北川景子 は ゆっち とデートから帰ってきました。
今からデートに行くのは、新垣結衣
新垣結衣 は ゆっち とデートに行きました。
新垣結衣 は ゆっち とデートから帰ってきました。
今からデートに行くのは、剛力彩芽
剛力彩芽 は ゆっち とデートに行きました。
剛力彩芽 は ゆっち とデートから帰ってきました。
堀北真希 は 恭平 とデートから帰ってきました。
(○・ω・)ノ——– Are you happy? ——–

さて、疑い深い私は NetBeans のプロファイラでスレッドの状態を確認してみました。( 注意:先ほどの実行結果とはことなります。)

1a

期待通りの動きをしてくれてます。(^_^) NetBeans のプロファイア手軽に使えて便利だね。

Semaphore 使える良い娘じゃないか!

もし、あなたが 恭平さん に素敵な女性とデートさせずに全ての女性を独り占めしたいとしたらこのプログラムをどのように変更したらいいでしょうか?

答えは簡単ですね!

私はヘルプを頼んだ 恭平さん に悪いのでプログラムの変更はいたしません。

どうしてもというかたはご自由に。(^_^;)

ちなみに今回のプログラムでは

CompletableFuture<Void> lovers1 = CompletableFuture.runAsync(() -> maki.play(), executor);

として ExecutorService を使いましたが

CompletableFuture<Void> lovers1 = CompletableFuture.runAsync(() -> maki.play());

として Fork/Join Framework を使うのもありです。

こどもの日の休日スペシャルはこれでお終いです。

食事する哲学者の問題Dining Philosophers Problem)に続く かも?

Hatena タグ: ,

NetBeans IDE から SSH 接続で GitHub を使ってみた。

Java NetBeans Ubuntu

お盆休みも今日が最後になったのにダラダラして終わることになった。(^_^;

ビール飲んでグダグダしながらこんなことを今さらしていたので記念にエントリーしておく。

最初に GitHub に新しいリポジトリを作成する。

そしてまだ SSD 公開鍵を設定してなければ設定しておく。

1

 

NetBeans IDE で新規プロジェクトを作成する。

2

 

Git ローカルリポジトリを作成する。

3

 

ローカルリポジトリを作成する場所を指定する。

4

 

出力ウィンドウでローカルリポジトリが作成されたことが解る。

5

 

プロジェクトウィンドウでもリポジトリのバッジが付いたことが確認できる。

6

 

HelloGitHub.java ファイルを add する。

7

 

そしてコミットする。

8

 

コミットされるファイルを確認し、解りやすいメッセージを書いておく。

GitHub は公開だと全世界と繋がるので地球標準の英語でメッセージを書いておくと良いことがあるかもしれない。

9

 

ローカルリポジトリにコミットした状態を Git リポジトリ・ブラウザで確認。

まだ寂しい状態であることが一目で解りますね。(ちょっと表現がおかしいけど気にしない。プレミアム・モルツのせいだ!)

10

 

それではリモートリポジトリにプッシュしましょう。

11

 

はじめてリモートリポジトリに接続する場合は下図のように必要事項を設定します。

これは SSH 接続を利用しています。(OpenSSH)

一度設定してしまえば後はラクチン、ラクチンです。

12

 

接続が完了すると下図のような画面が表示されます。

16

 

チェックをいれて次へ進めます。

17

 

終了ボタンを押してプッシュを実行します。

18

 

リモートリポジトリへのプッシュが完了したことを Git リポジトリ・ブラウザで確認します。

19

 

疑り深い人は GitHub のサイトをブラウザで開いて確認してみてください。

20

 

さらにソースコードを編集します。

21

 

変更されたことが色づけとバージョンラベルで確認できます。

22

 

さっきと同様にローカルリポジトリをコミットします。

23

 

そしてリモートリポジトリへプッシュします。

今度は先ほど設定したリモートリポジトリが選択されているので「次へ」ボタンを押すだけです。

24

 

25

 

26

 

さて、疑り深い人は GitHub のサイトをブラウザで開いて確認ですね。

27

 

完璧ですね。

28

 

ついでに履歴も確認。

29

 

30

 

NetBeans IDE で Git をそれなりに使うには十分ですね。

ただ、大規模なプロジェクトだと専用のツールを使ったほうが痒いところに手が届きます。

必要十分な機能は備えているみたいなんでやっぱり NetBeans IDE は素晴らしい!

Hatena タグ: ,,

JavaFX でさらに足し算のお勉強

JavaFX NetBeans

前回のプログラムを利用して今回も JavaFX で足し算アプリに手を加えてみることにしました。

今回追加する機能は アプリのウィンドウサイズの変更をできないようにする。

チェックボックスを利用して BGM を流せるようにする。

問題の難易度を選択できるようにトグルボタンを排他制御して可能にする。

ツールチップを設定する。

ニーモニックを設定する。

結局、こんな感じにできあがりました。

1

 

2

 

3

 

4

 

トグルボタンは私の実力ではニーモニックを正しく動作させることができなかったので諦めました。(>_<。)

素直にラジオボタンを使えばよかったかも・・・

トグルボタンの排他制御のイベント処理はかなり怪しいことをしています。

我ながらこれは無いだろうと思いながら他に良い方法を知らないので動けばいいやってのりでやってます。(オヒ

だからニーモニックが・・・・・ とどのつまりラジオボタンを使おう、今度からは。

いちおう、なんとか動いたので良しとしました。(^_^;)

それではそんなこんなでいい加減ですがプログラムを晒しておきます。

アプリのウィンドウサイズの変更をできないようにするために Calc2.java の 19 行目で

stage.setResizable(false);

としています。

チェックボックスを利用して BGM を流せるようにするために CalcFormController.java の 163 行目から 178 行目までで

チェックボックスにリスナーを設定して制御しています。

トグルボタンはグループ化して排他制御可能としてます。

これは JavaFX Scene Builder を使って簡単に設定できます。

トグルボタンのイベントをそれぞれ実装して JavaFX Scene Builder で結びつければいいだけです。

トグルボタンのグループも JavaFX Scene Builder で簡単に設定できます。便利!便利!

ただ前述したとおりトグルボタンが必ずどれか一つ選択状態にあるようにしたいため適当なことをやっています。

おそらく、なんだこれは?といいたくなるかもしれませんがスマートな方法を知らないのでこうなりました。(^_^;)

よってトグルボタンにニーモニックを設定しても上手く動作しなくなります。だからニーモニックはあきらめました。(ヲヒ

チェックボックス、テキストフィールド、ボタンにはニーモニックを JavaFX Scene Builder で簡単に設定できます。

プロパティの Text 欄に _ を先頭につけて記入し(_BGM)

5

 

Mnemonic Parsing のチェックボックスを ON にすればいいだけです。

6

 

ツールチップも同様に JavaFX Scene Builder を使えば楽勝です!

JavaFX Scene Builder のライブラリ Popup Controls から Tooltip をドラッグアンドドロップして

プロパティを設定してやればいいだけという非常に楽ちんな作業です。

7

 

以上、こんな感じでできあがりました。

Webstart: click to launch this app as webstart

ちょっと五月蠅くなってしまいましたがご勘弁を。

もっといろいろ楽しいことが出来るようなのでボチボチと遊んでみたいと思ってます。

cludia_2013_08_06_001

Hatena タグ: ,


« 古い記事 新しい記事 »