←フエルチラシノウラ。トップページへもどる。

【Java】大量データを送信してくる送信者からのデータを取りこぼさない方法。

Java スレッド notify wait レシーバ センダー 取りこぼさない方法 受信 送信

受信者側のことを全く考えずにガンガンデータ送信してくる送信者からのデータを漏れなく受信する方法です。

例えば、送信者が

1, 2, 3

というデータを順番に送信してきたとする。
そのとき、受信者は、

1, 2, 3

という順番でデータを受け取りたいわけだが、
1と2の間で別の長い処理Xをしていたがために2を受信し損ねてしまう。
結果、取得したデータは以下のようになる。

1, 3

これを防ぐためには、受信処理は受信専用のスレッドに任せてしまい、
長い処理Xを受信処理とは切り離してしまえばよいのである。

以下はそのサンプルソースです。
package hoge;
/**
* 受信者のことを全く考えずにデータをガンガン送信する送信者からの
* データを取りこぼさずに受信する方法のサンプル。
*/
public class Main {

/** 監視対象のデータクラス */
private Data data = new Data();

/**
* メイン
*
* @param args
*/
public static void main(String[] args) {
new Main();
}

/**
* コンストラクタ
*/
public Main() {

// レシーバを起動
Receiver receiver = new Receiver();
receiver.start();

// センダーを起動
Sender sender = new Sender();
sender.start();

while (true) {

/*
* ここで data.get() としてsenderからの送信を待ってもいいと思うかも知れませんが、
* ここでsenderからの受信を待つと、このあとのSleep(仮想的な長い処理)により、
* 処理中に送信データが流れてきて、データの取りこぼしが発生し得ます。
* だからこそ、Receiverを作って別スレッドとして外だししているのです。
*/

System.out.println("長ったらしい処理をしています。。。");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}

/**
* 受信専用クラス
* 余計な処理は入れず、ただ只管受信だけを行わせることにより、
* 送信者からのデータを受け損ねることを防ぎます。
* このスレッドクラスには単純に受信だけをさせるというところがミソです。
*/
class Receiver extends Thread {

public void run() {
while (true) {
// 受信待ち。。。
int count = data.get();
// 受信したら出力。
System.out.println("i got! " + count);
}
}
}

/**
* データクラスを只管カウントアップするスレッド
*
*/
class Sender extends Thread {

public void run() {
while (true) {
try {
// 一秒に一回カウントアップ
Thread.sleep(1000);
// カウントアップされるとnotifyAllによりwaitが解除され、レシーバが反応します。
data.countUp();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}

}

/**
* 監視対象のデータクラス
*/
class Data {

// カウントアップされるメンバ変数
private int i;

/**
* メンバ変数iをカウントアップします。
*
*/
private synchronized void countUp() {
System.out.println("countUp.");
i++;
notifyAll();
}

/**
* メンバ変数iが変化したらiを返します。
*
* @return i
*/
public synchronized int get() {
try {
System.out.println("wait.");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
return i;
}
}
}

http://goodjob.boy.jp/chirashinoura/id/134.html

作成日: 2007-04-19 23:57:12

最終更新日: 2007-04-20 00:00:32

▲このページの上へ