ガベージコレクション

第15章

Something obj = new Something();
  • 変数objは,Somethingクラスのインスタンスの参照したアドレスを保持している.
    Something obj1 = new Something();
    Something obj2 = obj1;
    obj1 = null;
  • obj1にnullを代入することで,どのアドレスも参照しない状態にする.このとき,obj2にSomethingクラスのインスタンスの参照を保持
    Something obj1 = new Something();
    Something obj2 = obj1;
    obj1 = null;
    obj2 = null;
  • obj2の参照もnullにすると,作ったSomethingクラスのインスタンスを参照できなくなる.このとき,ガベージ(ゴミ)となる.

ガベージコレクタ

  • ヒープ上に確保されたインスタンスのメモリ領域がガベージとなり,ガベージが蓄積されると,Java仮想マシンは,ガベージコレクションを始める.
  • どの変数からも参照されないインスタンスのメモリ領域を回収し,再利用する.

GcTest1.java:

public class GcTest1 {
    public static void main(String[] args) {
        while (true) {
            String s = new String("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
            System.out.println("残りメモリ = " + Runtime.getRuntime().freeMemory());
        }
    }
}

メモリ管理のためのメソッド

  • 利用可能なメモリの大きさを得る
    long free = Runtime.getRuntime().freeMemory();
  • 全てのメモリの大きさを得る
    long total = Runtime.getRuntime().totalMemory();
  • 最大メモリの大きさを得る
    long max = Runtime.getRuntime().maxMemory();
  • ガベージコレクションを動作させる
    Runtime.getRuntime().gc();
    または,
    System.gc();

スレッド

第16章

スレッドを作る方法

  • Threadクラスの拡張クラスを作る
    1. Threadクラスの拡張クラスを作る
    2. そのクラスのrunメソッドを宣言する
    3. そのクラスのインスタンスを作る
    4. startメソッドを呼び出す

CountTenA.java

Expand allFold all
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
-
-
|
|
-
|
!
!
-
-
|
!
!
!
public class CountTenA extends Thread {
    public static void main(String[] args) {
        CountTenA ct = new CountTenA();
        ct.start();
        for (int i = 0; i < 10; i++) {
            System.out.println("main:i = " + i);
        }
    }
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("run:i = " + i);
        }
    }
}
  • Runnableインターフェースを実装したクラスを作る
    1. Runnableインターフェースを実装したクラスを作る
    2. runメソッドを実装する
    3. そのクラスのインスタンスを作り,Threadオブジェクトを生成する
    4. Threadオブジェクトのstartメソッドを呼び出す

CountTenB.java

Expand allFold all
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
-
-
|
|
|
-
|
!
!
-
-
|
!
!
!
public class CountTenB implements Runnable {
    public static void main(String[] args) {
        CountTenB ct = new CountTenB();
        Thread th = new Thread(ct);
        th.start();
        for (int i = 0; i < 10; i++) {
            System.out.println("main:i = " + i);
        }
    }
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("run:i = " + i);
        }
    }
}

Threadを作る方法のまとめ

方法A方法B
用途簡単なクラス向け複雑なクラス向け
スーパークラスThreadクラス何でもよい
クラス宣言Threadクラスの拡張Runnableインターフェスの実装
スレッドの起動startメソッドThread経由でstartを起動
実行開始点runメソッドrunメソッド

2つのスレッドが同じフィールドに代入する例

pp.160
BadBank.java

Expand allFold all
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
-
|
-
|
|
|
-
|
|
!
|
!
!
public class BadBank {
    private int value = 0;
    public void addMoney(int money) {
        int currentValue = value;
        System.out.println(Thread.currentThread() + "が addMoney に入りました。");
        value += money;
        if (currentValue + money != value) {
            System.out.println(Thread.currentThread() + "で矛盾が発生しました!");
            System.exit(-1);
        }
        System.out.println(Thread.currentThread() + "が addMoney から出ました。");
    }
}

BadBankTest.java

Expand allFold all
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
-
|
-
|
!
-
-
|
|
!
!
-
|
|
|
!
!
public class BadBankTest extends Thread {
    BadBank bank;
    public BadBankTest(BadBank bank) {
        this.bank = bank;
    }
    public void run() {
        while (true) {
            bank.addMoney(100);
            bank.addMoney(-100);
        }
    }
    public static void main(String[] args) {
        BadBank bank = new BadBank();   // BadBankを生成
        new BadBankTest(bank).start();
        new BadBankTest(bank).start();
    }
}
$ javac javac BadBank.java BadBankTest.java
$ java BadBankTest

2つのスレッドが同じフィールドに代入する正しい例

GoodBank.java

Expand allFold all
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
-
|
-
|
|
|
-
|
|
!
|
!
!
public class GoodBank {
    private int value = 0;
    public synchronized void addMoney(int money) {
        int currentValue = value;
        System.out.println(Thread.currentThread() + "が addMoney に入りました。");
        value += money;
        if (currentValue + money != value) {
            System.out.println(Thread.currentThread() + "で矛盾が発生しました!");
            System.exit(-1);
        }
        System.out.println(Thread.currentThread() + "が addMoney から出ました。");
    }
}

GoodBankTest.java

Expand allFold all
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
-
|
-
|
!
-
-
|
|
!
!
-
|
|
|
!
!
public class GoodBankTest extends Thread {
    GoodBank bank;
    public GoodBankTest(GoodBank bank) {
        this.bank = bank;
    }
    public void run() {
        while (true) {
            bank.addMoney(100);
            bank.addMoney(-100);
        }
    }
    public static void main(String[] args) {
        GoodBank bank = new GoodBank();   // GoodBankを生成
        new GoodBankTest(bank).start();
        new GoodBankTest(bank).start();
    }
}
$ javac GoodBank.java GoodBankTest.java 
$ java GoodBankTest

スレッドを止める

pp.169

Expand allFold all
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
-
|
-
|
!
-
-
|
!
!
!
class Runner extends Thread {
    private boolean running = true;
    public void stopRunning() {
        running = false;
    }
    public void run() {
        while (running) {
            doCommand();
        }
    }
}

スレッドを待たせる

pp.171
Periodic.java

Expand allFold all
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
-
-
-
|
|
-
|
-
!
!
!
!
public class Periodic {
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            int tm = i * 1000;
            System.out.println("Start sleep:tm = " + tm);
            try {
                Thread.sleep(tm);
            } catch (InterruptedException e) {
            }
        }
    }
}

スレッドを終了を待つ

pp.173
JoinTest.java

Expand allFold all
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
-
-
|
|
|
|
-
|
-
|
!
|
!
-
|
-
|
-
|
!
|
!
!
public class JoinTest extends Thread {
    public static void main(String[] args) {
        JoinTest th = new JoinTest();
        System.out.println("main:はじめ");
        th.start();
        System.out.println("main:終了待ちに入る");
        try {
            th.join();
        } catch (InterruptedException e) {
            System.out.println(e);
        }
        System.out.println("main:おわり");
    }
    public void run() {
        System.out.println("run:スレッド実行開始");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            System.out.println(e);
        }
        System.out.println("run:スレッド実行終了");
    }
}

スレッド同士を待ち合わせる

pp.174
ProducerConsumer.java

Expand allFold all
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
-
-
|
|
|
|
|
!
!
 
-
|
|
|
-
|
|
|
!
-
-
|
|
!
|
|
|
|
!
-
-
|
|
!
|
|
|
|
|
!
!
 
-
|
|
-
|
!
-
-
-
|
|
!
|
-
!
!
-
|
|
|
!
-
-
|
|
-
!
!
!
 
-
|
-
|
!
-
-
-
|
-
|
!
|
!
-
!
!
-
|
|
!
-
-
|
|
-
!
!
!
public class ProducerConsumer {
    public static void main(String[] args) {
        MyQueue queue = new MyQueue(3);
        Producer producer = new Producer(queue);
        Consumer consumer = new Consumer(queue);
        producer.start();
        consumer.start();
    }
}
 
class MyQueue {
    int[] intbuf;
    int start;
    int count;
    public MyQueue(int size) {
        intbuf = new int[size];
        start = 0;
        count = 0;
    }
    public synchronized void put(int n) throws InterruptedException {
        while (count >= intbuf.length) {
            System.out.println(Thread.currentThread().getName() + " wait : バッファの空きを待つ");
            wait();
        }
        int end = (start + count) % intbuf.length;
        intbuf[end] = n;
        count++;
        notifyAll();
    }
    public synchronized int take() throws InterruptedException {
        while (count == 0) {
            System.out.println(Thread.currentThread().getName() + " wait : データを待つ");
            wait();
        }
        int n = intbuf[start];
        start = (start + 1) % intbuf.length;
        count--;
        notifyAll();
        return n;
    }
}
 
class Producer extends Thread {
    static final int END = -1;
    MyQueue queue = null;
    Producer(MyQueue queue) {
        this.queue = queue;
    }
    public void run() {
        try {
            for (int i = 0; i < 100; i++) {
                int n = produce(i);
                queue.put(n);
            }
            queue.put(Producer.END);
        } catch (InterruptedException e) {
        }
    }
    int produce(int n) {
        sleepRandomly();
        System.out.println("Producer:" + getName() + "は " + n + " を生産完了");
        return n;
    }
    void sleepRandomly() {
        try {
            int n = (int)(Math.random() * 1000);
            Thread.sleep(n);
        } catch (InterruptedException e) {
        }
    }
}
 
class Consumer extends Thread {
    MyQueue queue = null;
    Consumer(MyQueue queue) {
        this.queue = queue;
    }
    public void run() {
        try {
            while (true) {
                int n = queue.take();
                if (n == Producer.END) {
                    break;
                }
                consume(n);
            }
        } catch (InterruptedException e) {
        }
    }
    void consume(int n) {
        System.out.println("Consumer:" + getName() + "は " + n + " を消費中");
        sleepRandomly();
    }
    void sleepRandomly() {
        try {
            int n = (int)(Math.random() * 1000);
            Thread.sleep(n);
        } catch (InterruptedException e) {
        }
    }
}

説明課題

  • 以下のrobocode大会上位者は,自機のプログラムの説明を行ってください.資料はプレゼンテーションソフト(OpenOffice, NeoOffice, MS Office等)を使うこと.
    • 対象者
    • E095714 喜納直輝
    • E095731 新城幸之祐
    • E095703 岩瀬翔
    • E095763 與那嶺 貴雄
    • E095726 島袋将悟
  • 説明すべき点
    • プログラムの特徴
    • 勝因
    • 改善案,等
  • 発表日
    • 2月8日


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2013-06-20 (木) 14:45:23 (2338d)