#navi(Programming_II/09)
#contents
//*moodle 
//-[[moodle:https://tarkus.eva.ie.u-ryukyu.ac.jp/moo/]]
*ガベージコレクション [#laac8401]
第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クラスのインスタンスを参照できなくなる.このとき,ガベージ(ゴミ)となる.
**ガベージコレクタ [#k439ceeb]
-ヒープ上に確保されたインスタンスのメモリ領域がガベージとなり,ガベージが蓄積されると,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());
         }
     }
 }

**メモリ管理のためのメソッド [#ic3f3251]
-利用可能なメモリの大きさを得る
 long free = Runtime.getRuntime().freeMemory();
-全てのメモリの大きさを得る
 long total = Runtime.getRuntime().totalMemory();
-最大メモリの大きさを得る
 long max = Runtime.getRuntime().maxMemory();
-ガベージコレクションを動作させる
 Runtime.getRuntime().gc();
または,
 System.gc();
*スレッド [#j4cfd1c8]
第16章~

**スレッドを作る方法 [#p8101a9a]
-Threadクラスの拡張クラスを作る
++Threadクラスの拡張クラスを作る
++そのクラスのrunメソッドを宣言する
++そのクラスのインスタンスを作る
++startメソッドを呼び出す

CountTenA.java

#code(java){{
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インターフェースを実装したクラスを作る
++Runnableインターフェースを実装したクラスを作る
++runメソッドを実装する
++そのクラスのインスタンスを作り,Threadオブジェクトを生成する
++Threadオブジェクトのstartメソッドを呼び出す



CountTenB.java
#code(java){{
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を作る方法のまとめ [#j48e6834]
||方法A|方法B|h
|用途|簡単なクラス向け|複雑なクラス向け|
|スーパークラス|Threadクラス|何でもよい|
|クラス宣言|Threadクラスの拡張|Runnableインターフェスの実装|
|スレッドの起動|startメソッド|Thread経由でstartを起動|
|実行開始点|runメソッド|runメソッド|



**2つのスレッドが同じフィールドに代入する例 [#y7a82d0e]
pp.160~
BadBank.java
#code(java){{
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

#code(java){{
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つのスレッドが同じフィールドに代入する正しい例 [#rad287c7]
GoodBank.java
#code(java){{
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
#code(java){{
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

**スレッドを止める [#te46fe47]
pp.169
#code(java){{
class Runner extends Thread {
    private boolean running = true;
    public void stopRunning() {
        running = false;
    }
    public void run() {
        while (running) {
            doCommand();
        }
    }
}
}}
**スレッドを待たせる [#dbceb6ce]
pp.171~
Periodic.java
#code(java){{
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) {
            }
        }
    }
}
}}
**スレッドを終了を待つ [#ted6039f]
pp.173~
JoinTest.java
#code(java){{
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:スレッド実行終了");
    }
}
}}
**スレッド同士を待ち合わせる [#p8c49eeb]
pp.174~
ProducerConsumer.java

#code(java){{
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) {
        }
    }
}
}}

*説明課題 [#pa99b437]
-以下のrobocode大会上位者は,自機のプログラムの説明を行ってください.資料はプレゼンテーションソフト(OpenOffice, NeoOffice, MS Office等)を使うこと.
--対象者
--E095714 喜納直輝
--E095731 新城幸之祐
--E095703 岩瀬翔
--E095763 與那嶺 貴雄
--E095726 島袋将悟

-説明すべき点
--プログラムの特徴
--勝因
--改善案,等
-発表日
--2月8日

#navi(Programming_II/09)

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS