サンプルから学ぶJava スレッド及びスレッドの同期
2009/02/17 14:06Update
スレッドとは何か、なぜスレッドは必要なのか、スレッドの同期は何などなど、サンプルから初心者向けにわかりやすく解説したいと思います。
Javaスレッド概要、サンプル
Javaスレッドの実装方法、状態、優先度、同期などスレッドとは
スレッドはCPU利用の単位です。一つのスレッドはプロセスにある一つの処理を表します。複数のスレッド(マルチスレッド)が実行される時、JVMは優先度の高いスレッドの方にCPUを多く割り当て、早く終らせるようになります。
スレッド (コンピュータ) - Wikipedia
本文は
1、スレッドクラスの実装方法
2、スレッドの生成
3、スレッドの同期
4、スレッドのグループ化
などについて学びます。
サンプル
サンプルから見てみます。
「書店店員は本を売る」
1、仮に2人の店員は20冊の本を売るとします。
2、条件としては、すでにほかの店員に売り出された本を売ることはできません
処理対象:20冊の本
スレッド:
スレッドA:店員A
スレッドB:店員B
また、「売り出された本を売ることはできない」ことは、スレッドの同期を取る必要があると考えられます。
■ファイルリスト:
Book.java 本クラス
SellBookRunnable.java 「本を売る」クラス。スレッドの実装方法1
SellBookThread.java 「本を売る」クラス。スレッドの実装方法2
CallSellBook.java 「スレッドの生成」クラス
SellBookRunnable.javaとSellBookThread.java両方を実装する必要はありません、どちらの実装を使うか選べればいいのだと思います。
Book.javapublic class Book {
private String name;
private boolean sold = false;
public Book(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isSold() {
return sold;
}
public void setSold(boolean sold) {
this.sold = sold;
}
}
SellBookRunnable.javaimport java.util.List;
//Runnableインタフェース実装
public class SellBookRunnable implements Runnable {
private String saleMan; //店員
private List<Book> bookList; //売る対象となる本のリスト
public SellBookRunnable(String saleMan, List<Book> bookList) {
this.saleMan = saleMan;
this.bookList = bookList;
}
public void run() {
for (int i = 0; i < bookList.size(); i++) {
Book book = bookList.get(i);
sellBook(book);
}
}
/**
* 本を売る
*
* @param book Book
*/
private void sellBook(Book book) {
//synchronizedを利用してスレッドの同期を取ります。synchronized (book)でbookは他の店員に取られないように制御します。
synchronized (book) {
if (book.isSold()) { //既に売った場合
return;
} else {
try {
//他のスレッドに実行されるチャンスを与えるため、0.5秒をあけます「本を取った時点から売ったまでの時間」。
Thread.sleep(500);
} catch (Exception e) {
}
//売り出したとのフラグを設定します
book.setSold(true);
//売りましたよ
System.out.println("[" + saleMan + "]" + book.getName() + " sold out:"
+ book.isSold() + ". by "
+ Thread.currentThread().getName());
}
}
}
}
SellBookThread.javaimport java.util.List;
public class SellBookThread extends Thread {
private String saleMan;
private List<Book> bookList;
public SellBookThread(String saleMan, List<Book> bookList) {
this.saleMan = saleMan;
this.bookList = bookList;
}
public void run() {
for (int i = 0; i < bookList.size(); i++) {
Book book = bookList.get(i);
sellBook(book);
}
}
/**
* 本を売る
*
* @param book Book
*/
private void sellBook(Book book) {
//synchronizedを利用してスレッドの同期を取ります。synchronized (book)でbookは他の店員に取られないように制御します。
synchronized (book) {
if (book.isSold()) { //既に売った場合
return;
} else {
try {
//他のスレッドに実行されるチャンスを与えるため、0.5秒をあけます「本を取った時点から売ったまでの時間」。
Thread.sleep(500);
} catch (Exception e) {
}
//売り出したとのフラグを設定します
book.setSold(true);
//売りましたよ
System.out.println("[" + saleMan + "]" + book.getName() + " sold out:"
+ book.isSold() + ". by "
+ Thread.currentThread().getName());
}
}
}
}
CallSellBook.javaimport java.util.ArrayList;
import java.util.List;
//スレッドの生成、実行
public class CallSellBook {
/**
* マルチスレッドで「本を売る」ことをシミュレーションします
*/
public static void main(String[] args) {
//方法1
callSellBookThread();
//or
//方法2
//callSellBookRunnable();
}
//本を売る
//SellBookThread(Threadクラスの実装)を利用します
public static void callSellBookThread() {
List <Book>bookList = getBookListForSale(); //売る対象となる本リスト
//店員SaleMan1
Thread t1 = new SellBookThread("SaleMan1", bookList);
//店員SaleMan2
Thread t2 = new SellBookThread("SaleMan2", bookList);
//店員SaleMan1:「本を売る」処理開始
t1.start();
//店員SaleMan2:「本を売る」処理開始
t2.start();
}
//本を売る
//SellBookRunnable(Runnableインタフェースの実装)を利用します
public static void callSellBookRunnable() {
List <Book>bookList = getBookListForSale(); //売る対象となる本リスト
//店員SaleMan1
Thread t1 = new Thread(new SellBookRunnable("SaleMan1", bookList));
//店員SaleMan2
Thread t2 = new Thread(new SellBookRunnable("SaleMan2", bookList));
//店員SaleMan1:「本を売る」処理開始
t1.start();
//店員SaleMan2:「本を売る」処理開始
t2.start();
}
//売る対象となる本リスト
public static List<Book> getBookListForSale() {
List <Book>bookList = new ArrayList();
for (int i = 0; i < 20; i++) {
Book book = new Book("Book" + i);
bookList.add(book);
}
return bookList;
}
}
■実行結果(CallSellBook):
[SaleMan1]Book0 sold out:true. by Thread-0
[SaleMan2]Book1 sold out:true. by Thread-1
[SaleMan2]Book2 sold out:true. by Thread-1
[SaleMan2]Book3 sold out:true. by Thread-1
[SaleMan2]Book4 sold out:true. by Thread-1
[SaleMan2]Book5 sold out:true. by Thread-1
[SaleMan1]Book6 sold out:true. by Thread-0
[SaleMan1]Book7 sold out:true. by Thread-0
[SaleMan1]Book8 sold out:true. by Thread-0
[SaleMan1]Book9 sold out:true. by Thread-0
[SaleMan1]Book10 sold out:true. by Thread-0
[SaleMan1]Book11 sold out:true. by Thread-0
[SaleMan2]Book12 sold out:true. by Thread-1
[SaleMan2]Book13 sold out:true. by Thread-1
[SaleMan2]Book14 sold out:true. by Thread-1
[SaleMan2]Book15 sold out:true. by Thread-1
[SaleMan2]Book16 sold out:true. by Thread-1
[SaleMan2]Book17 sold out:true. by Thread-1
[SaleMan1]Book18 sold out:true. by Thread-0
[SaleMan1]Book19 sold out:true. by Thread-0
[SaleMan2]Book1 sold out:true. by Thread-1
[SaleMan2]Book2 sold out:true. by Thread-1
[SaleMan2]Book3 sold out:true. by Thread-1
[SaleMan2]Book4 sold out:true. by Thread-1
[SaleMan2]Book5 sold out:true. by Thread-1
[SaleMan1]Book6 sold out:true. by Thread-0
[SaleMan1]Book7 sold out:true. by Thread-0
[SaleMan1]Book8 sold out:true. by Thread-0
[SaleMan1]Book9 sold out:true. by Thread-0
[SaleMan1]Book10 sold out:true. by Thread-0
[SaleMan1]Book11 sold out:true. by Thread-0
[SaleMan2]Book12 sold out:true. by Thread-1
[SaleMan2]Book13 sold out:true. by Thread-1
[SaleMan2]Book14 sold out:true. by Thread-1
[SaleMan2]Book15 sold out:true. by Thread-1
[SaleMan2]Book16 sold out:true. by Thread-1
[SaleMan2]Book17 sold out:true. by Thread-1
[SaleMan1]Book18 sold out:true. by Thread-0
[SaleMan1]Book19 sold out:true. by Thread-0
次のページ:解説(スレッドの生成、優先度、グループ化、同期など)
Sponsored Link
Comments
- Relative Articles
- Java開発及び実行環境の構築 | Linux篇 - (2008/08/31 20:34)
- Java開発及び実行環境の構築 | Windows篇 - (2008/08/31 21:18)
- 5分でJava Hello World! - (2008/08/31 22:13)
- Java言語の制御構文 - 条件分岐if/else/else if - (2008/10/01 21:30)
- Java言語の繰り返し制御構文 - for文 - (2008/10/03 18:22)
- Java言語の繰り返し制御構文 - do ... while文 - (2008/10/03 21:23)
- Java言語の繰り返し制御構文 - while文 - (2008/10/03 21:32)
- Java言語の基礎 - javacコマンドによるコンパイル - (2008/10/10 17:58)
- Java アクセス修飾子概要 - (2008/10/29 18:31)
- Javaアノテーション機能 概要 - (2009/02/12 13:06)