SlideShare a Scribd company logo
1 of 82
Javaプログラミング入門
第8回
今日の講義
• スレッド
スレッドとは
• スレッド(thread)は、もともと「糸」という意
味
• Javaでは「プログラムを実行している主体」の
ことを指す
• プログラムの実行の流れに従いながらプログラ
ムを読んでいく
▫ ペンでなぞっていくと1本の糸になる
▫ このようなプログラムをシングルスレッドと言う

• 例えるなら小人が1人動いているのと同じ
シングルスレッドのイメージ図
if文を分岐しようが、
while文で繰り返そうが
どんなに複雑な処理をし
ていても一本の糸になる
マルチスレッドとは何か
• Java言語はマルチスレッドを扱うことが出来る
言語
• マルチスレッドのプログラムの場合、「いまプ
ログラムのどこを実行していますか?」と訊か
れても、「はい、ここです」と示すことは出来
ない
• マルチスレッドの場合、小人は複数人登場する
マルチスレッドのイメージ図
マルチスレッドの注意点
• マルチスレッドを考える上で注意すべき点は、
複数のスレッドが同じタイミングで同じメソッ
ドの同じ文を実行しているかもしれない、とい
うこと
▫ 独自に歩きまわっていた小人が、同時に同じ店に
入ったパターン
 互いに関わりがない間は問題は発生しない
 2人が同時に1台のレジに並ぶと?
排他制御
• 1台しかレジがない場合、小人が複数人同時に来
ても処理が出来ない
▫ 1列に並んでもらって、1度に1人ずつ会計していく

• マルチスレッドも同じで、互いに干渉しあう状
況では、スレッドは1列に並んでもらった方が安
全
▫ このような機構を排他制御(mutual exclusion
control)と呼ぶ
同期
• 普段は独立して歩き回っている小人たちに、協
力して働いてもらいたい時もある
• 情報集めをしているたくさんのスレッドが仕事
を終え、情報が全部揃ったところで、それを処
理するスレッドが動き出すようなパターン
▫ スレッドの待ち合わせやスレッドの間の通信機能
が必要
▫ このような機構を同期(synchronization)と呼ぶ
身近にあるマルチスレッドの例
• GUI(グラフィカルユーザーインターフェース)
▫ 表計算ソフトが計算を行っている時もメニュー
バーは表示されていて、ブラウジングもできる

• ネットワーク上のサーバ
▫ phpは通常シングルスレッド
※参考
http://www.php.net/manual/ja/intro.pthreads.php

• 状況を監視するようなアプリケーション
▫ タスクマネージャー
サーバとマルチスレッドの例

クライアント

通信

サーバ
スレッド

クライアント

通信
スレッド

クライアント

通信

スレッド
スレッドを作る2つの方法
• Java言語でのスレッドの作り方には2種類ある
A) Threadクラスの拡張クラスを作る
B) Runnableインターフェースを実装したクラスを
作る
Threadクラス(方法A)
• Threadクラスの拡張クラスを作ってスレッドを
動かすには、次のような手順を踏む必要がある
1.
2.
3.
4.

Threadクラスの拡張クラスを作る
そのクラスのrunメソッドを宣言する
そのクラスのインスタンスを作る
startメソッドを呼び出す
Threadクラスでスレッドを作る例
• CountTenA.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);
}
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("run:i = " + i);
}
}
}
詳しく読んでみる
• CountTenAクラスは、Threadクラスを拡張して作ら
れている
• CountTenAクラスには、2つのメソッドmainとrun
が宣言されている
▫ mainは、このクラスをアプリケーションとして実行
しようとした時に最初に呼び出されるメソッド
▫ runは、Threadクラスで宣言されているメソッドで、
スレッドが動き始めるときに呼ばれるメソッド
▫ runというメソッドは、スレッドにとってのmainメ
ソッドに相当する、と考えることが出来る
詳しく読んでみる2
• mainメソッド内の3行目、CountTenAオブジェ
クト(インスタンス)を生成しているが、ここで
はまだスレッドは動き出していない
• ct.start()
▫ このstartが実際のスレッドを起動するメソッド
▫ startメソッドの内部で、新たなスレッドが作ら
れ、そのスレッドのrunメソッドが呼び出される
糸が生まれる瞬間
startメソッドの中

新しいスレッドの誕生

runメソッドへ

startメソッドから
帰る
詳しく読んでみる3
• startメソッドが呼び出されると、新たなスレッ
ド、新たな流れ、新たな糸が生まれる。そし
て、その糸はrunメソッドで始まり、runメソッ
ドで終わる
▫ この道を歩くのは、mainスレッドの小人とは別の
小人

• runメソッドでやっていることは、変数iを0~9
までぐるぐる回してその内容を表示すること。
• 9まで表示したらfor文が終わり、このスレッド
も終了する
Runnableインターフェース(方法B)
• CountTenAでは、スレッドの実行開始点とし
て、runメソッドを宣言
• Threadクラスの拡張クラスではなくても、run
メソッドを新しいスレッドの開始点とすること
が出来る。Runnableインターフェースはrunメ
ソッドを持っており、Runnableインターフェー
スを実装するクラスは、runメソッドを実装しな
ければならない
Runnableインターフェースを使ったス
レッドを作る例
• CountTenB.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);
}
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("run:i = " + i);
}
}
}
クラス宣言の違い
• CountTenAは
▫ public class CountTenA extends Thread

• CountTenBは
▫ public class CountTenB implements Runnable
スレッド開始の違い
• CountTenAは

CountTenA ct = new CountTenA();
ct.start();
▫ CountTenAのメソッドstartを呼び出している
▫ CountTenAにはstartメソッドは宣言されていないが、
スーパークラスのメソッドを呼び出している

• CountTenBは

CountTenB ct = new CountTenB();
Thread th = new Thread(ct);
th.start();
▫ CountTenBのオブジェクト(インスタンス)を引数に渡
してThreadのオブジェクトを生成し、Threadクラス
のstartメソッドを呼び出している
スレッドを作る2つの方法のまとめ
A) Threadクラスの拡張クラスを宣言する
B) Runnableインターフェースを実装したクラス
を宣言する
メリット・デメリット
• 方法Aは、とにかく手軽なこと
• ただし、Javaではスーパークラスは1つしか持つこ
とが出来ないため、他のクラスの拡張クラスにする
ことはできなくなる
• 方法Bは、方法Aのデメリットを解消するために用
意された方法
• クラス階層の下の方に位置するクラスであっても、
インターフェースは実装出来る
• ただし、そのスレッドを動かすためには、別途
Threadクラスのインスタンスを生成し、そのstartメ
ソッドを呼び出す必要がある
スレッドを作る2つの方法の比較
方法A

方法B

用途

簡単なクラス向け

複雑なクラス向け

スーパークラス

Threadクラス

なんでも良い

クラスの宣言

Threadクラスの拡張
class CountTenA extends
Thread {
....
}

Runnableインターフェースの実装
class CountTenB implements
Runnable {
....
}

スレッドの起動

startメソッドを呼ぶ
CountTenA a = new
CountTenA();
a.start();

Thread経由でstartを呼ぶ
CountTenB b = new CountTenB();
Thread th = new Thread(b);
th.start();

実行開始点

runメソッド

runメソッド
インターフェースの設計
• スレッドに限った話ではなく、インターフェー
ス設計の全般に適応出来る
• つまり、ある機能を持ったクラスを作りたい
時、1つはその機能を持ったクラスの拡張クラス
にしてしまう方法、もう1つは、その機能を実現
するためのメソッドをまとめてインターフェー
スにし、そのインターフェースを実装するクラ
スを作る方法がある
演習問題1
• 「こんにちは!」というあいさつを1秒おきに表
示するPrintHelloクラスと、それを実現するス
レッドとなるLabelPrinterクラスを次のように作
ろうとしている。誤りがあるため、実行結果が
以下のようになるよう修正しなさい。
• 【実行結果】
こんにちは!
こんにちは!
こんにちは!
... ←続く
LabelPrinter.java
public class LabelPrinter {
String label = "no label";
public LabelPrinter(String label) {
this.label = label;
}
@Override
public static void run() {
while (true) {
System.out.println(label);
Thread.sleep(1000);
}
}
}
PrintHello.java
public class PrintHello {
public static void main(String[] args) {
LabelPrinter th = new LabelPrinter("こ
んにちは!");
th.start();
}
}
2つのスレッドが同じフィールドに代入
したらどうなるか?
• 次のクラスBadBankは「悪い銀行」を表すクラ
ス
• 1つのフィールドvalueと1つのメソッド
addMoneyを持つ
• addMoneyは預入と引出を行うメソッド
• addMoneyの引数が0より大きい時は預入、0よ
り小さい時は引出しを表す
2つのスレッドが同じフィールドに代入
する例
• BadBank.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から出ました");
}
}
BadBankを使う例
public class BadBankTest extends Thread {
BadBank bank;
public BadBankTest(BadBank bank) {
this.bank = bank;
}
@Override
public void run() {
while(true) {
// 100円預入
bank.addMoney(100);
// 100円引出し
bank.addMoney(-100);
}
};
public static void main(String[] args) {
BadBank bank = new BadBank();
// 2つのスレッドで同じインスタンスを扱う
new BadBankTest(bank).start();
new BadBankTest(bank).start();
}
}
なぜ矛盾は発生するのか?
• 現在残高を保存する
int currentValue = value;

という部分と、矛盾チェックを行う
if (currentValue + money != value) {
....
}

という部分の間で、「スレッドの切り替え」が起こ
る可能性があるから
▫ 1つのスレッドが現在残高を保存し、矛盾がないか
チェックする前に、別のスレッドがvalueにmoneyを
足し込んでしまうから!
2つのスレッドが同じフィールドに代入
する正しい例
• 違いはたった1つ
▫ synchronized

というキーワードが、addMoneyメソッドにつ
いただけ
• このキーワードを付けるだけで、先ほどの矛盾
が発生しなくなる
BadBankを直したGoodBank
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から出ました");
}
}
GoodBankを使う例
public class GoodBankTest extends Thread {
GoodBank bank;
public GoodBankTest(GoodBank bank) {
this.bank = bank;
}
@Override
public void run() {
while(true) {
// 100円預入
bank.addMoney(100);
// 100円引出し
bank.addMoney(-100);
}
};
public static void main(String[] args) {
GoodBank bank = new GoodBank();
new GoodBankTest(bank).start();
new GoodBankTest(bank).start();
}
}
どうして矛盾が発生しないのか?
• addMoneyにsynchronizedを付けた時、1つのス
レッドがaddMoneyを実行中であれば、他のス
レッドはaddMoneyを実行することが出来ない
ため
GoodBankの様子
変数bank
GoodBankのインスタンス

他のスレッドは
待たされる

public synchronized void addMoney(int money)
{
ロック
}

スレッド1が実行中
ロック(lock)
• 「鍵」のこと
• 部屋に1人でいたい時、部屋に入って鍵をかけ
る。
• 他の人は部屋に入ってこれなくなる
• スレッドは、synchronizedが付いたメソッド
(synchronizedメソッド)に入るときに、鍵をか
け、そのメソッドから出る時に、鍵を外す
• これにより、そのメソッドに入れるスレッドは1
つだけになる
鍵をかけている「部屋」とは?
• スレッドがsynchronizedメソッドに入るときに
は、そのインスタンスに対して鍵をかけている
• 1人の小人(スレッド)がその部屋(インスタンス)
に鍵をかける(ロックをかける)と、他の小人は
その部屋(インスタンス)の鍵のある部屋
(synchronizedメソッド)には入れない
• synchronizedはメソッドに鍵をかけているわけ
ではなく、インスタンスにかけている
synchronized
• あるスレッドがsynchronizedメソッドを実行し
ている最中であっても、そのインスタンスの
synchronizedではないメソッドならば、どのス
レッドも実行できる
• あるスレッドがsynchronizedメソッドを実行し
ていても、別のインスタンスメソッドは、
(synchronizedであってもなくても)実行できる
• 1つのスレッドは、1つのインスタンスの
synchronizedメソッドを続けて実行出来る(自分
自身が鍵によって締め出されることはない)
synchronizedメソッドとsynchronized
ブロック
• メソッド全体ではなく、メソッドの一部分だけ
でロックをかけることができる
synchronized(ロックオブジェクト) {
....
}
• この場合には、ロックをかけるオブジェクトを
明示的に指定する
addMoneyの例
public void addMoney(int money) {
synchronized (this) {
// 現在残高を保存
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から出ました
");
}
}
演習問題2
• 演習問題1のLabelPrinterを使って、「おはよ
う!」「こんにちは!」「こんばんは!」をそ
れぞれ表示するスレッド3つを動かすクラス
PrintHello3を宣言しなさい
演習問題3
• CountTenA.javaではrunメソッドを実行してい
るのは、1つのスレッドだった。新たなスレッド
を1つだけ生成するのではなく、3個生成して動
作するようにプログラムを書き換えなさい。ク
ラスの名前はCountTen3とする。
• また、表示を行っているのはどのスレッドかわ
かるようにしなさい。必要であれば、次のメ
ソッドを使用すること。
▫ public final String getName()
▫ public static Thread currentThread()
クラスメソッドとsynchronized
• メソッドにはインスタンスメソッドとクラスメ
ソッドの2種類がある
• どちらにもsynchronizedメソッドにすることが
出来る
• ただし、クラス・メソッドがsynchronizedメ
ソッドになっているとき、ロックしているもの
は何か?
▫ インスタンスメソッドの時は、インスタンス自身
(this)をロックしていたが、クラスメソッドの場
合は、クラス自身をロックすることになる
スレッドを止めるには?
• スレッドはrunメソッドの実行が終了すれば、その
スレッドは動いていなくなる
• スレッドが自分で自分を終了したい場合には、run
メソッドを終わらせればよい
• 次のrunメソッドはdoCommandを1000回実行する
と止まる
public void run () {
for (int i = 0; i < 1000; i++) {
doCommand();
}
}
自分以外のスレッドを終了させるに
は?
• スレッドに前もって「終了するための条件」を埋め込んでお
き、外からその条件を操作すればよい
public class Runner extends Thread {
private boolean running = true;
public void stopRunning() {
running = false;
}
@Override
public void run() {
while (running) {
doCommand();
}
}
}
スレッドを少し待たせたい場合はどう
する?
• スレッドの動作が速すぎて不都合があるとき
• メソッドを繰り返し呼ぶ必要があるが、時間間
隔を開けたいとき
待ちたいときにはThread.sleep
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) {

}

}

}

}
演習問題4
• 約3秒毎に"***"を10回表示するスレッドと、約5秒ごとに
"====="を10回表示するスレッドを、それぞれ1つずつ動か
すクラスをThreadクラスの拡張クラスとして作りなさい。
• 【実行例】※実行する度に変化する
***
=====
***
***
=====
***
=====
***
***
=====
演習問題5
• 演習問題4をRunnableインターフェースを実装
して作成しなさい
スレッドの終了を待つにはどうする?
• 他のスレッドに仕事をさせておき、そのスレッ
ドの実行が終了したら自分の仕事を再開したい
とき、Threadのjoinというメソッドを使用する
• joinの引数にタイムアウト時間を指定すること
も出来る
スレッドの終了を待つjoin
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:おわり");
}
スレッドの終了を待つjoin
@Override
public void run() {
System.out.println("run:スレッド実行開始");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
System.out.println(e);
}
System.out.println("run:スレッド実行終了");
}
}
スレッド同士を待ち合わせたいときは
どうする?
• 複数のスレッドはまったく別のところを走って
いるけども、片方のスレッドが別のスレッドか
ら通知が来るのを待つような状況
▫ スレッドPは、データを次々に作って配列に格納
する
▫ スレッドCは、配列に格納されたデータを次々に
処理する

• スレッドPは生産者(Producer)、スレッドCは
データの消費者(Consumer)を表すとする
スレッドの待ち合わせ
• スレッドPが先行した場合には、キューは一杯
になってしまい、スレッドCがデータを消費し
て、キューに空き領域を作るまで、スレッドP
は待たされる
• スレッドCが先行した場合は、キューは空に
なってしまい、スレッドPがデータを生産し
て、キューに詰めるまで、スレッドCは待たさ
れる
スレッドの待ち合わせの例
• クラス構成
▫ ProducerConsumerクラス(mainメソッド)
▫ MyQueueクラス(スレッドPとスレッドCが参照す
る配列)
▫ Producerクラス(Threadを継承、キューにデータ
を入れる)
▫ Consumerクラス(Threadを継承、キューのデータ
を消費する)
ProducerConsumer.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();
}
}
MyQueue.java(1)
public 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();
}
MyQueue.java(2)
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;
}
}
Producer.java(1)
public class Producer extends Thread {
static final int END = -1;
MyQueue queue = null;
public Producer(MyQueue queue) {
this.queue = queue;
}
@Override
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) {
System.out.println(e);
}
};
Producer.java(2)
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) {
}
}
}
Consumer.java(1)
public class Consumer extends Thread {
MyQueue queue = null;
public Consumer(MyQueue queue) {
this.queue = queue;
}
@Override
public void run() {
try {
while(true) {
int n = queue.take();
if (n == Producer.END) {
break;
}
consume(n);
}
} catch (InterruptedException e) {
}
}
Consumer.java(2)
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) {
}
}
}
ProducerConsumerクラス
• このクラスは以下の処理を行う
1. MyQueueのインスタンスを生成する。キューの大き
さは3とする
2. 生産者スレッドproducerを生成する。通信用の
キューを渡す
3. 消費者スレッドconsumerを生成する。通信用の
キューを渡す
4. 生産者スレッドproducerを起動する
5. 消費者スレッドconsumerを起動する

•

これ以降は、producerとconsumer2つのスレッド
が独自に、キューを共有しながら動く
MyQueueクラス
• スレッドの制御を行いながらデータの出し入れ
を行うクラス
• マルチスレッドの環境でも正しく動作するクラ
スやメソッドのことをスレッドセーフ(thread
safe)と呼ぶ
条件待ちの決まり文句
synchronized aMethod(...) throws
InterruptedException {
while( ! 求めている条件) {
wait();
}
必要な処理を行う
notifyAll();
}
MyQueueクラス
• putメソッド
▫ 引数nをデータとして格納するメソッド
▫ intbufが一杯ならば、そのスレッドは待ち状態になる
▫ 他のスレッドがnotifyAllすると、スレッドは動作可能
状態になる

• takeメソッド
▫ キューからデータを抜き出すメソッド
▫ キューが空だったら、waitメソッドで待ち状態に入る
▫ 他のスレッドがnotifyAllすると、動き始め、条件がみ
たされたことを確認するとwhile文を抜ける
条件のチェックの部分は、なぜifでは
なくwhileなのか?
• while (count >= intbuf.length)
• waitで待っていたスレッドが動き出した、とい
うのは、単に誰かがnotify(あるいはnotifyAll)し
たというだけのことで、そのスレッドがwaitし
ていた条件が満たされたとは限らないから
• つまり、スレッドがwaitの呪縛から逃れて実際
の処理に向かう時、もう一度条件をチェックす
る必要がある。
waitやnotify、notifyAllを発行するとき
のメソッドはなぜsynchronizedでなけ
ればならないか?
• 必ずしもsynchronizedメソッドである必要はな
いが、wait、notify、notifyAllを実行するとき、
対象となるオブジェクトにロックをかけていな
ければならない
• ロックをかける代表的な方法がsynchronizedメ
ソッド
synchronizedの中でwaitしてもいいの
か?
• synchronizedの中では、そのオブジェクトに関
して1つのスレッドしか動けないが、waitしても
いいのだろうか?
• waitは、そのスレッドが持っているそのオブ
ジェクトのロックを一旦外すので、良い
• waitを発行するとsynchronizedブロックの前で
待っていたスレッドが動作可能状態になる。
• Thread.sleepはオブジェクトのロックははずさ
ない
waitはどのクラスのメソッドか?
• waitはObjectクラスのメソッド
• すなわち、Javaのオブジェクトはすべてロック
対象になる
• スレッドは、waitメソッドを実行するとオブ
ジェクトごとに用意されたウエイトセット(wait
set)という待合室にはいり、notifyされるまで実
行を一時停止する
notifyAllしたら、waitしていたスレッ
ドはすぐ動くのか?
• 「実行可能状態」にはなるが、すぐに動き出す
わけではない
• notifyAllを発行したスレッドがそのオブジェク
トのロックを開放しない限り、他のスレッドは
走り出さない
notifyとnotifyAllの違いは何か?
• notifyは、ウエイトセットの中にある1つのス
レッドだけを実行再開する
• notifyAllはウエイトセットの中にあるスレッド
をすべて実行再開する
匿名クラスでインスタンス生成
• Runnableはインターフェースなので、newでインス
タンス生成することはできない
• しかし、以下のようなコードなら書くことが出来る
Runnable r = new Runnable() {
@Override
public void run() {
...
}
}
r.start();
• この名前のないクラスのことを匿名クラスという
演習問題6
• GoodBankTest.javaはGoodBankのインスタンス
を生成して、預金の預入と引出しを行った。
• これを変更して、銀行口座がたった1つしかない
プログラムにしなさい。クラスの名前は
OneBankTestとOneBankにすること。
• ヒント:OneBankのフィールドやメソッドを
staticにし、それに合わせてOneBankTestを作成
する
演習問題7
• 次のSingleThreadProgramクラスはJob(仕事)ク
ラスのオブジェクトを10個作ってworkというメ
ソッドを呼び出し続けるクラスである。このプ
ログラムをマルチスレッドに書き換えなさい。
Job.java
public class Job {
int num;
public Job(int n) {
num = n;
}
public void work() {
System.out.println(this + " is working." );
try {
int n = (int) Math.random() * 10000;
Thread.sleep(n);
} catch (InterruptedException e) {
}
}
public String toString() {
return "[Job " + num + "]";
}
}
SingleThreadProgram.java
public class SingleThreadProgram {
Job[] jobs;
public SingleThreadProgram(int jobcount) {
jobs = new Job[jobcount];
for (int i = 0; i< jobcount; i++) {
jobs[i] = new Job(i);
}
}
public void workAllJobs() {
for (int i = 0; i < jobs.length; i++) {
jobs[i].work();
}
}
public static void main(String[] args) {
SingleThreadProgram self = new SingleThreadProgram(10);
while(true) {
self.workAllJobs();
}
}
}
参考文献
• Java言語 プログラミングレッスン[第3版]下
▫ 結城浩[著]

More Related Content

What's hot

Installation et configuration d'apache tomcat
Installation et configuration d'apache tomcatInstallation et configuration d'apache tomcat
Installation et configuration d'apache tomcat
Manassé Achim kpaya
 

What's hot (20)

現場で使えるDynamoDBと冪等デザインパターン
現場で使えるDynamoDBと冪等デザインパターン現場で使えるDynamoDBと冪等デザインパターン
現場で使えるDynamoDBと冪等デザインパターン
 
Oracle Cloud Infrastructure:2023年2月度サービス・アップデート
Oracle Cloud Infrastructure:2023年2月度サービス・アップデートOracle Cloud Infrastructure:2023年2月度サービス・アップデート
Oracle Cloud Infrastructure:2023年2月度サービス・アップデート
 
vSphere環境での自動化とテスト
vSphere環境での自動化とテストvSphere環境での自動化とテスト
vSphere環境での自動化とテスト
 
SQL Server replication overview (JP)
SQL Server replication overview (JP)SQL Server replication overview (JP)
SQL Server replication overview (JP)
 
차세대 서비스 핵심 모바일헬스
차세대 서비스 핵심 모바일헬스차세대 서비스 핵심 모바일헬스
차세대 서비스 핵심 모바일헬스
 
EmbulkとDigdagとデータ分析基盤と
EmbulkとDigdagとデータ分析基盤とEmbulkとDigdagとデータ分析基盤と
EmbulkとDigdagとデータ分析基盤と
 
M. Scanu - Sistema unitario di metadati. Componente relativa ai metadati stru...
M. Scanu - Sistema unitario di metadati. Componente relativa ai metadati stru...M. Scanu - Sistema unitario di metadati. Componente relativa ai metadati stru...
M. Scanu - Sistema unitario di metadati. Componente relativa ai metadati stru...
 
レイヤードアーキテクチャを意識したPHPアプリケーションの構築
レイヤードアーキテクチャを意識したPHPアプリケーションの構築レイヤードアーキテクチャを意識したPHPアプリケーションの構築
レイヤードアーキテクチャを意識したPHPアプリケーションの構築
 
【BS4】時は来たれり。今こそ .NET 6 へ移行する時。
【BS4】時は来たれり。今こそ .NET 6 へ移行する時。 【BS4】時は来たれり。今こそ .NET 6 へ移行する時。
【BS4】時は来たれり。今こそ .NET 6 へ移行する時。
 
最適なOpenJDKディストリビューションの選び方 #codetokyo19B3 #ccc_l5
最適なOpenJDKディストリビューションの選び方 #codetokyo19B3 #ccc_l5最適なOpenJDKディストリビューションの選び方 #codetokyo19B3 #ccc_l5
最適なOpenJDKディストリビューションの選び方 #codetokyo19B3 #ccc_l5
 
2022 May - Shoulders of Giants - Amsterdam - Kotlin Dev Day.pdf
2022 May - Shoulders of Giants - Amsterdam - Kotlin Dev Day.pdf2022 May - Shoulders of Giants - Amsterdam - Kotlin Dev Day.pdf
2022 May - Shoulders of Giants - Amsterdam - Kotlin Dev Day.pdf
 
PHP-FPM の子プロセス制御方法と設定をおさらいしよう
PHP-FPM の子プロセス制御方法と設定をおさらいしようPHP-FPM の子プロセス制御方法と設定をおさらいしよう
PHP-FPM の子プロセス制御方法と設定をおさらいしよう
 
SchoolAdmin - School Fees Collection & Accounting Software
SchoolAdmin - School Fees Collection & Accounting SoftwareSchoolAdmin - School Fees Collection & Accounting Software
SchoolAdmin - School Fees Collection & Accounting Software
 
Reactive Extensionsで非同期処理を簡単に
Reactive Extensionsで非同期処理を簡単にReactive Extensionsで非同期処理を簡単に
Reactive Extensionsで非同期処理を簡単に
 
Spring bootでweb セキュリティ(ログイン認証)編
Spring bootでweb セキュリティ(ログイン認証)編Spring bootでweb セキュリティ(ログイン認証)編
Spring bootでweb セキュリティ(ログイン認証)編
 
JSUG 20141127 「Spring Bootを用いたドメイン駆動設計」
JSUG 20141127 「Spring Bootを用いたドメイン駆動設計」JSUG 20141127 「Spring Bootを用いたドメイン駆動設計」
JSUG 20141127 「Spring Bootを用いたドメイン駆動設計」
 
Chapitre8: Collections et Enumerations En Java
Chapitre8: Collections et Enumerations En JavaChapitre8: Collections et Enumerations En Java
Chapitre8: Collections et Enumerations En Java
 
NuxtでAPIサーバー立ててみた
NuxtでAPIサーバー立ててみたNuxtでAPIサーバー立ててみた
NuxtでAPIサーバー立ててみた
 
Springを何となく使ってる人が抑えるべきポイント
Springを何となく使ってる人が抑えるべきポイントSpringを何となく使ってる人が抑えるべきポイント
Springを何となく使ってる人が抑えるべきポイント
 
Installation et configuration d'apache tomcat
Installation et configuration d'apache tomcatInstallation et configuration d'apache tomcat
Installation et configuration d'apache tomcat
 

Similar to Javaプログラミング入門【第8回】

Web技術勉強会 20110723
Web技術勉強会 20110723Web技術勉強会 20110723
Web技術勉強会 20110723
龍一 田中
 
WordBench Kobe jQueryどうでしょう
WordBench Kobe jQueryどうでしょうWordBench Kobe jQueryどうでしょう
WordBench Kobe jQueryどうでしょう
Hishikawa Takuro
 
Kink: invokedynamic on a prototype-based language
Kink: invokedynamic on a prototype-based languageKink: invokedynamic on a prototype-based language
Kink: invokedynamic on a prototype-based language
Taku Miyakawa
 
第1回内容の振り返り
第1回内容の振り返り第1回内容の振り返り
第1回内容の振り返り
skowata
 

Similar to Javaプログラミング入門【第8回】 (20)

JavaScriptクイックスタート
JavaScriptクイックスタートJavaScriptクイックスタート
JavaScriptクイックスタート
 
React.jsでクライアントサイドなWebアプリ入門
React.jsでクライアントサイドなWebアプリ入門React.jsでクライアントサイドなWebアプリ入門
React.jsでクライアントサイドなWebアプリ入門
 
Web技術勉強会 20110723
Web技術勉強会 20110723Web技術勉強会 20110723
Web技術勉強会 20110723
 
TotalViewを使った代表的なバグに対するアプローチ
TotalViewを使った代表的なバグに対するアプローチTotalViewを使った代表的なバグに対するアプローチ
TotalViewを使った代表的なバグに対するアプローチ
 
Java8から17へ
Java8から17へJava8から17へ
Java8から17へ
 
WordBench Kobe jQueryどうでしょう
WordBench Kobe jQueryどうでしょうWordBench Kobe jQueryどうでしょう
WordBench Kobe jQueryどうでしょう
 
Start!! Ruby
Start!! RubyStart!! Ruby
Start!! Ruby
 
Kink: invokedynamic on a prototype-based language
Kink: invokedynamic on a prototype-based languageKink: invokedynamic on a prototype-based language
Kink: invokedynamic on a prototype-based language
 
Serializabilityとは何か
Serializabilityとは何かSerializabilityとは何か
Serializabilityとは何か
 
第1回内容の振り返り
第1回内容の振り返り第1回内容の振り返り
第1回内容の振り返り
 
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
 
⑯jQueryをおぼえよう!その2
⑯jQueryをおぼえよう!その2⑯jQueryをおぼえよう!その2
⑯jQueryをおぼえよう!その2
 
デザパタIntro
デザパタIntro デザパタIntro
デザパタIntro
 
Groovyで楽にSQLを実行してみよう
Groovyで楽にSQLを実行してみようGroovyで楽にSQLを実行してみよう
Groovyで楽にSQLを実行してみよう
 
ScaLa+Liftとか
ScaLa+LiftとかScaLa+Liftとか
ScaLa+Liftとか
 
Javaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組みJavaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組み
 
Inside frogc in Dart
Inside frogc in DartInside frogc in Dart
Inside frogc in Dart
 
Ruby test double
Ruby test doubleRuby test double
Ruby test double
 
Java開発の強力な相棒として今すぐ使えるGroovy
Java開発の強力な相棒として今すぐ使えるGroovyJava開発の強力な相棒として今すぐ使えるGroovy
Java開発の強力な相棒として今すぐ使えるGroovy
 
JavaScript 非同期処理 入門
JavaScript非同期処理 入門JavaScript非同期処理 入門
JavaScript 非同期処理 入門
 

More from Yukiko Kato

Javaデザインパターン入門【第2回】
Javaデザインパターン入門【第2回】Javaデザインパターン入門【第2回】
Javaデザインパターン入門【第2回】
Yukiko Kato
 
Javaプログラミング入門【第6回】
Javaプログラミング入門【第6回】Javaプログラミング入門【第6回】
Javaプログラミング入門【第6回】
Yukiko Kato
 
[Ps11]ネットワーク第4回
[Ps11]ネットワーク第4回[Ps11]ネットワーク第4回
[Ps11]ネットワーク第4回
Yukiko Kato
 
HTTPとは(HerokuとADTで実践編)
HTTPとは(HerokuとADTで実践編)HTTPとは(HerokuとADTで実践編)
HTTPとは(HerokuとADTで実践編)
Yukiko Kato
 

More from Yukiko Kato (20)

Javaデザインパターン入門【第3回】
Javaデザインパターン入門【第3回】Javaデザインパターン入門【第3回】
Javaデザインパターン入門【第3回】
 
Javaデザインパターン入門【第2回】
Javaデザインパターン入門【第2回】Javaデザインパターン入門【第2回】
Javaデザインパターン入門【第2回】
 
Javaプログラミング入門【第9回】
Javaプログラミング入門【第9回】Javaプログラミング入門【第9回】
Javaプログラミング入門【第9回】
 
ネットワーク第9回
ネットワーク第9回ネットワーク第9回
ネットワーク第9回
 
ネットワーク第8回目
ネットワーク第8回目ネットワーク第8回目
ネットワーク第8回目
 
Javaプログラミング入門【第7回】
Javaプログラミング入門【第7回】Javaプログラミング入門【第7回】
Javaプログラミング入門【第7回】
 
ネットワーク第7回
ネットワーク第7回ネットワーク第7回
ネットワーク第7回
 
[PS11]ネットワーク第6回
[PS11]ネットワーク第6回[PS11]ネットワーク第6回
[PS11]ネットワーク第6回
 
Javaプログラミング入門【第6回】
Javaプログラミング入門【第6回】Javaプログラミング入門【第6回】
Javaプログラミング入門【第6回】
 
ネットワーク第6回
ネットワーク第6回ネットワーク第6回
ネットワーク第6回
 
ネットワーク第5回
ネットワーク第5回ネットワーク第5回
ネットワーク第5回
 
[PS11]ネットワーク第5回
[PS11]ネットワーク第5回[PS11]ネットワーク第5回
[PS11]ネットワーク第5回
 
Javaプログラミング入門【第5回】
Javaプログラミング入門【第5回】Javaプログラミング入門【第5回】
Javaプログラミング入門【第5回】
 
[Ps11]ネットワーク第4回
[Ps11]ネットワーク第4回[Ps11]ネットワーク第4回
[Ps11]ネットワーク第4回
 
Javaプログラミング入門【第4回】
Javaプログラミング入門【第4回】Javaプログラミング入門【第4回】
Javaプログラミング入門【第4回】
 
ネットワーク第4回目
ネットワーク第4回目ネットワーク第4回目
ネットワーク第4回目
 
Javaプログラミング入門【第3回】
Javaプログラミング入門【第3回】Javaプログラミング入門【第3回】
Javaプログラミング入門【第3回】
 
ネットワーク第3回目
ネットワーク第3回目ネットワーク第3回目
ネットワーク第3回目
 
Javaプログラミング入門【第2回】
Javaプログラミング入門【第2回】Javaプログラミング入門【第2回】
Javaプログラミング入門【第2回】
 
HTTPとは(HerokuとADTで実践編)
HTTPとは(HerokuとADTで実践編)HTTPとは(HerokuとADTで実践編)
HTTPとは(HerokuとADTで実践編)
 

Javaプログラミング入門【第8回】