- PR -

Javaのスレッド、ソケットの機構について

1
投稿者投稿内容
Makoto
大ベテラン
会議室デビュー日: 2004/03/31
投稿数: 133
投稿日時: 2004-03-31 11:56
これからJavaで開発(OS:Solaris)を行う予定なのですが、
いくつかわからないことがありますので質問させていただきます。
※従来まで、VC++で開発をしておりました。

【質問1】スレッドの実装に関して

VC++(Windows)の場合、スレッド間でのイベント処理は、メッセージ処理にて実装していると思います。
(これによりスレッド同士の処理の流れの分離が可能となっている。)

Javaの場合に、スレッド間で通信を行う場合に、(APIやクラスライブラリで)
メッセージ駆動にする方法は提供されているのでしょうか?
※関数Call以外の方法を知りたい!

サンプルなどを見ても、
スレッド1と、スレッド2がいた場合に、スレッド1でスレッド2のメンバ関数をCALL
しているような処理しか見たことがありません。
これでは、スレッドを分けている意味がないと思うのですが...


【質問2】ソケット通信に関して

Javaでは、VC++でいうところの非同期型のソケットクラス(CAsyncSocketクラス)は、
SocketChannel クラスと思いますが、CAsyncSocket:nRecieve関数にあたる関数もあるのでしょうか?

現状では、ソケットで電文を受信した場合に、自動でアプリケーション側へ通知してくる制御方法がないように思えます。
自前でアプリにタイマーを設定し、一定周期ごとに電文を受信しているかどうかを
見に行くしかない?ように思えます。
それ以外に方法は無いのでしょうか?

以上、わかる方がいらっしゃいましたら、回答お願いします。
シュン
ぬし
会議室デビュー日: 2004/01/06
投稿数: 328
お住まい・勤務地: 東京都
投稿日時: 2004-03-31 12:22
引用:

Makotoさんの書き込み (2004-03-31 11:56) より:

サンプルなどを見ても、
スレッド1と、スレッド2がいた場合に、スレッド1でスレッド2のメンバ関数をCALL



そのサンプル自体がどこかおかしいと思いますよ。スレッドという概念とオブジェクトのインスタンスメソッドあるいはクラスメソッドの関係は、そのような文章表現になるような関係ではないですよね。

おそらくイベントキュー+ワーカースレッドのような仕組みが欲しい、ということだと推測しますが、そのような理解でよいでしょうか?J2SEのコアAPIには、そのような仕組みを抽象化したレイヤーは存在せず、各自で自作しているのが現状だと思います。あるいは、各ベンダが提供するEnterprise Message Queueの実装に対して、J2EEのJMS APIでアクセスする、といったあたりでしょうか。

ちなみに、JDK1.5の「Concurrentユーティリティクラス追加」の一つとして、上記のような仕組みがコアAPIに同梱されます。
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ThreadPoolExecutor.html
リファレンス実装のEAは公開されています。近くプロダクト実装が公開予定ですので、それまで待ってもよいかもしれません。

引用:

【質問2】ソケット通信に関して



「受信イベントドリブン」という仕組みは、APIで提供されてはいないようです。

多数のソケットに対して少数のスレッドで監視する仕組みは、JDK1.4で追加になったnonblocking I/Oで行います。APIはselect()システムコールに似せて作ってあります。java.nio.channels.Selectorクラスと、select()によるソケット監視の仕組みについてお調べください。

その仕組みの上に、「受信イベントドリブン」の仕組みを作りこむことは難しくないと思います。あるいは上記のThreadPoolExecutorと組み合わせてもよいでしょう。
かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2004-03-31 13:01
任意の2つのスレッド間で、通信を行うAPIは無いですが、AWT/Swingを使用している場合、Event Dispatch Threadとの間で通信を行うことは可能です。

java.awt.Toolkit#getSystemEventQueue()でEventQueueを取得し、EventQueueに対してpostEventメソッドでイベントとしてメッセージを送出します。

送出するイベントは、java.awt.AWTEventから派生させます。
コンポーネントに対してComponent#processEvent()をオーバーライドすれば、イベントを受け取ることができます。

送出するイベントをjava.awt.AWTEventからだけでなく、java.awt.ActiveEventからも派生させ、ActiveEvent#dispatch()を実装することで、java.awt.Component以外のオブジェクトに対してもイベントとしてメッセージを送出することができます。
受け取り先のインターフェースは自由に決めることができます。
シュン
ぬし
会議室デビュー日: 2004/01/06
投稿数: 328
お住まい・勤務地: 東京都
投稿日時: 2004-03-31 14:17
シングルCPU環境下で、ワーカースレッドが1個だけで良いのなら、かずくんさんのおっしゃるように、AWTのEventQueueの仕組みを流用させてもらうと、作りこみをしないで済むので、よいですね。

ですが、マルチCPUやIntelのHyperThreadingなど時分割多重化をせずに複数スレッドの並列実行が可能な環境があって、その利点を生かすためにワーカースレッドを複数実行状態にしたい場合は、この方法は適切ではなくなってしまいます。
1

スキルアップ/キャリアアップ(JOB@IT)