- 主に柏周辺でプログラム言語Javaを中心にプログラム談義をする会です。
- 正式名称は「柏 Effective Java 第2版 読書会」。Effective Javaを持ち寄って気になる章をみんなで読み進める会です。
- でもほんとは「モンハンやろうぜ!」の会。→誕生秘話
2010-09-11 14:00〜 上野予定 延期
- 2011-02-27 14:00〜 上野予定。題材は並行処理、他を予定。
- 秋葉原開催。参加人数5名。
- 10章並行性を中心に読み進めた。synchronized, volatileの話に入るには前提条件としてJVMのメモリーキャッシュの話があると理解が早かった。その値への書き込みが単一スレッドからのみに限定されており、別スレッドからの読み込みにキャッシュを参照させたくない場合はvolatileで良い。でも単一スレッドからのみ書き込みしますという言語的宣言はJavaだとできないんだよね。なのでこの辺はドキュメントだよりになるね。
- アトミック性とはなにか、有名なところではインクリメント演算子やlong, doubleの代入はアトミックにならない、などの話。
- SimpleDateFormatの使い方についてのお説教。SimpleDateFormatは内部に状態を持ち、同期化されないのでformat()やparse()などをマルチスレッドでアクセスした場合、結果は壊れる可能性がある。
private static final DateFormat df = new SimpleDateFormat("yyyy/MM/dd"); // oh no!
- 例題、GUIアプリ等でよくある、メインスレッドとイベントスレッドの2つの間で確実にデータを受け渡すにはどうしたらいいか。スタートボタンを押したときにMenuStatusのstartButtonPushedフラグをtrueにしてみよう。
public class MenuStatus {
private boolean startButtonPushed = false; // volatileなくて良い
public synchronized void setStartButton(final boolean value) {
startButtonPushed = value;
}
public synchronized boolean isStartButtonPushed() { // ゲッターもsynchronized掛かっていることに注目
return startButtonPushed;
}
- セッターにつけたsynchronizedはわかりやすい。オブジェクトに対するロック(モニタ)を取得し、同時に単一スレッドのみが書き込みを行うようにするためのガード。ゲッターにもsynchronizedが着いてる理由はなぜかな?これが重要。
- ここで、MenuStatusインスタンスに対して、フラグを精査し、falseであれば更新を行うという処理を書くとしよう。たしかにセッターもゲッターもsynchronizedではあるのだが2つの呼び出しはアトミックでないため、精査終わった時には状態が変わっている可能性がある。
public class Test {
public void doUpdate() {
if (!menuStatus.isStartButtonPushed()) { // ここで調べた内容は
menuStatus.setStartButton(true); // ここに来るまでに何者かにより変更されている可能性がある
}
}
}
- こういう場合はMenuStatus内にアトミックな処理として実装するのがいいでしょう。
- 2010-07-25 14:00〜 参加人数7名
- 今回のお題はCUIで動作する掲示板を作ってみよう!CUIコマンドで動作し、Writeクラスで1行発言、Readクラスで全件表示、RMDBを使って実装しよう。
- SQLインジェクションのおさらいから、StatementよりPreparedStatement使おうの話。
- 定数インターフェイスを使わない方が良い理由から、そもそもインターフェイスとはなんぞやというお話(項目19 型を定義するためだけにインターフェイスを使用する)
- スタティックインポートの話やそもそもインポート文は何をしているのかの話
- コネクションなどのリソースを確実に管理する話、すべての変数をfinalにしつつリソースを確実にクローズする話。
- メソッド呼び出しの異常終了を通知するのに返り値を使ったほうがいいのか、Exceptionを投げるのがいいのかの話(項目61 抽象概念に適した例外をスローする)
- finalを付けると何が変わるのか、イミュータブルクラスの話、あるビーンクラスがありますこれをイミュータブルクラスに変えてみような話(項目15 可変性を最小限にする)、それに関連してビルダーパターンの話(項目2 数多くのパラメーターに直面した時にはビルダーパターンを検討する)
- 2010-06-26 14:00〜 参加人数5人
- 事前に出されたJavaでlsプログラムを作ってみよう!のお題を元に進んだ。CollectionやMap、Setの話題、HashMapの実装についての話等上がる。Comparable.compareTo()関連項目として「第3章すべてのオブジェクトに共通のメソッド」の「項目8 equalsをオーバーライドする時は一般契約に従う」を読む。サンプルコード書いてくれた方々どうもありがとうございました。
- HTTPのレスポンスを完全に受け取る前にコネクションが切断された時の動作はどうなるのかという話題。Tomcatの動作とPHPの動作の違い。
- カレントディレクトリの取得はどうやるのが正しいのかの議論、結論出ず。System.getProperty("user.dir") には根拠のない違和感を感じるが、new File(".") のように"."(ドット)でカレントディレクトリを表すのは絶対に環境依存しないのか?lsプログラムの場合カレントディレクトリをJava内で取得するより、対象パスを必ず引数で受け取るようにする逃げ道の話、等。
- 2010-05-30 14:00〜 参加人数6人
- 読書会では第5章ジェネリックスが中心。
- 主にListのGenericsが中心だったがIteratorについての話題になると、なぜList.get(int)を使わずにIteratorを使うべきなのか、などの話も上がった。ArrayList.ItrとLinkedList.Itrの違い。Iteratorの参照するデータへのアクセス方法の関連で、staticのメンバークラスと非staticのメンバークラスの違いの話など。
- 第10章プログラミング一般・他の型が適切な場所では文字列を避ける、について、書籍管理システムを想定しての設計方法についての議論。int Book.getBookType() の発想にはどんな弊害があるのか、またどんな方法がスマートなのか、転じてenumの正体の話など。
- Javaに限った話ではないが小数点を扱う場合は正確でない場合があるのでBigDecimal使った方がよい話題、など。
- 何故かモンハンやらなかったなぁ…
- 2010-04-10 14:00〜
- 今回は事前に用意したクイズなどは無し。読書会は第9章「例外」が中心。
- 例外繋がりでNullについての話、Nullは型を持ってなくて気持ち悪い、そもそもNullを排除してPGできる、Maybe型を参考にしたNull排除方法の紹介から関数型言語についての話、HaskellやConcurrent Clean、Schera等、主にがくぞーさんの講義。
- マルチスレッドも話題に上がった。primitiveのlongとdoubleへの代入は実はアトミックじゃないんだよ、な話や、トランザクションとロック周りの話等。
- DIV教についてのお説教。HTMLに限らず言語の生まれた背景を知ることは、その言語の思想や設計を理解するうえで助けになるよね、という話等。
- 2009-12-06 14時〜18時
- クイズとして1問printAllを出題。
- 読書会では第4章「クラスとインターフェイス」から項目13「クラスとメンバーへのアクセス可能性を最小限にする」が中心。
- 特に熱かった話はクラスとインスタンスの関係、静的と動的の関係例えばクラスフィールドとインスタンスフィールドの違いは何か、アクセス修飾子をオーバーライド時には狭めることができない理由、継承による"is a"関係、Object.clone()の妙な振る舞い、フィールドへのマルチスレッドアクセス時に意図しない挙動が起こり得る、など。
- 出題のprintAll。このコードは特にJavaである必要はなく、実効性能も度外視でforやwhile、String Join系のライブラリも使わずにネイティブだけでできるかな?
package jp.hutcraft.nazo;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class PrintAll {
public static void main(String[] args) {
List<String> words =
new ArrayList<String>(Arrays.asList(new String[]{
"all", "your", "base", "are",
"belong", "to", "us"}));
printAll(words);
}
private static void printAll(List<String> words) {
// ↓これをforを使わずに同じ動作をするように書く
// for (String s : strings) {
// System.out.println(s);
// }
}
}
- 2009-07-25 12:00〜 参加人数6人
- サンプルプログラムとしてW氏の作成した抽選プログラムをみんなでリファクタリングして持ち寄り、発表した。
|