Edited at

synchronized のメモ

More than 1 year has passed since last update.

リファクタリングのためコードを見てたら

何回か見て忘れてしまったものが出たので忘れないようにメモしました。


synchronized とは?

synchronizedとは排他制御のことで、

排他制御=複数のプロセス(またはスレッド)が同時に入ることを防ぐことである

らしいです。


試してみる

言葉だけだとしっくり来なかったので

直接試してみました。

前提のイメージとして、

家族が一人ずつお風呂に入るイメージです。

(一人が終わるまで入ってはいけません。)

「メインメソッドのあるメインクラス」


MainClass.java

public class MainClass {

public static void main(String[] args) {
Bathroom bathroom = new Bathroom();
FamilyTread father = new FamilyTread(bathroom, "父");
FamilyTread mother = new FamilyTread(bathroom, "母");
FamilyTread sister = new FamilyTread(bathroom, "姉");
FamilyTread me = new FamilyTread(bathroom, "私");

father.start();
mother.start();
sister.start();
me.start();
}

}


Threadを継承した家族に対するクラス」


FamilyTread.java

class FamilyTread extends Thread {

private Bathroom mBathroom;
private String mName;

FamilyTread(Bathroom bathroom, String name) {
this.mBathroom = bathroom;
this.mName = name;
}

public void run() {
mBathroom.openDoor(mName);
}

}


「家族クラスから呼ばれて作業をするクラス」

class Bathroom {

void openDoor(String name) {
System.out.println(name + "「お風呂に入ります!」");
for (int count = 0; count < 100000; count++) {
if (count == 1000) {
System.out.println(name + "「お風呂に入りました。」");
}
}
System.out.println(name + "「お風呂から出ました!」");
}
}


何回か実行した結果

スクリーンショット 2016-12-12 17.17.56.png

父がまだお風呂に入ってるのに...!

順番がめちゃくちゃになってしまいました。(たまたま正しい順番になったりもします)

そこでsynchronizedを使うとお風呂(スレッド)に同時に入ることを防ぐことができると。


synchronized を使ってみる

Bathroomクラスの openDoorメソッドに synchronizedをつけてみました。

class Bathroom {

synchronized void openDoor(String name) {
System.out.println(name + "「お風呂に入ります!」");
for (int count = 0; count < 100000; count++) {
if (count == 1000) {
System.out.println(name + "「お風呂に入りました。」");
}
}
System.out.println(name + "「お風呂から出ました!」");
}
}


結果

スクリーンショット 2016-12-12 17.30.31.png

ちゃんとひとりづつ入るようになりました!


参照

http://www.techscore.com/tech/Java/JavaSE/Thread/3/