こんなネタがありました。
static変数を使用して、複数のスレッドが走るアプリケーションを作成した場合、static変数は、JavaVM上一つのアドレス空間しか指さないため、更新処理を行うと競合します。
以前知らなかったのですが、final修飾をつけたオブジェクトでもインスタンス変数内の変数は、操作可能です。ですので、static finalとして定義されたインスタンス内のstaticではない変数は、static変数のように振舞ってしまうようです。そんなオブジェクトをmutableというらしいです。
グローバル変数は、基本的に使用しなくてもアプリケーションは作成可能なはずなので、個人的には使用しません。
しかし、何回も領域確保するような変数を、システムがスコープになるグローバル変数を使用すると、速度が欲しいプログラムなどは効果がでるそうです。
私は、天才プログラマではないので、危険を省みないプログラムはかけません。。
グローバル変数は使わず、デザインパターンを愛します。
以下テストしたソース。
public class MutableTest implements Runnable {
private static int x = 1;//staticメソッド内で確保されたfinalかつimutableな変数。
private Point p1; //←スレッド内でnew用 mutableなオブジェクト。
private static final Point p2 = new Point(1, 1); //final static mutableなオブジェクト。
String name;
public MutableTest(String name) {
this.name = name;
p1 = new Point(1, 1); //mutableなオブジェクトの初期化。
}
public void run() {
while(true) {
synchronized (this.getClass().getName().intern()) {
System.out.println(name +":x" + (x++) + ":p1.y" + (p1.x++) + ":p2.y" + (p2.x++));
}
}
}
public static void main(String[] args) {
Thread t1 = new Thread(new MutableTest("Test1"));
Thread t2 = new Thread(new MutableTest("Test2"));
t1.start();
t2.start();
}
}
class Point {
int x = 0; //←Pointのインスタンスがstaticとして定義された場合、static変数と同様な動作をする。
int y = 0; //←Pointのインスタンスがstaticとして定義された場合、static変数と同様な動作をする。
private Point() {}
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
mail
コメントする