• 締切済み

Threadについて

細かい質問なのですが、 1.一つのthreadを走らせるプログラムを2つ(二回)走らせるのと、 2.同じthreadを2つ走らせるプログラムを一つ走らせるのでは どう違うのでしょうか? 1(●)(●) 2(●●) 一応伝えにくいのですがこの違いについて質問したくなった経緯は以下です。 現在javaでUSB経由の音声の取得を行っています。マイクから拾った音声をそのままイヤホンに出力するプログラムです。USBは2つついています。(仮にA,Bとさせていただきます) 前者の一つのthreadを走らせるプログラム2つですと、まずUSB[A]をライン入力の音源として一つ走らせた後に音源をBに変えてからもう一つを走らせると出力側は2つの音声を同時に再生してくれます。 しかし、後者の場合、Aが選択されている状態で一つスレッドを動かし音源をBに選択し直してから次のスレッドを動かすプログラムにしているにも関わらずBの音声は取得されず、Aのみとなってしまいます。おそらくAを二倍?拾っています。 もし質問内容に違いがなければこのようなことは起きないかと思っています。単純に自分の技術不足かもしれませんが・・・・ 説明が上手く出来なかったのですが、質問は以上です。 特に音が一つになったことは分かりづらかったら気にしないでください。違いが分かればうれしいです。

みんなの回答

  • ninoue
  • ベストアンサー率52% (1288/2437)
回答No.2

sunのjava チュートリアルを先ずチェックしてください。 "java サウンド チュートリアル sun" 等としてサーチして下さい。  javax.sound.midi, javax.sound.sampled 等の解説がありますが、 sampledが一般のステレオ録音、再生等に対応しているようです。 (実際に使った事はありませんので...)

回答No.1

まず、2のマルチスレッドで音源Bの音を拾わない原因ですが、恐らく、スレッドの処理が((1)USBから音を拾う→(2)拾った音を出力する)という処理を無限ループさせているためではありませんか? もしそうなら、((1)USBから音を拾う→(2)拾った音を出力する→(3)Thread.sleep(10)で10msecの間、制御を放棄する)というループにすれば、音源Aのループがsleepすると、音源Bのスレッドが動いて音を拾って出力後、同じくsleep()すると、今度は音源Aのスレッドが動くはずです。こうすれば、2つのスレッドが交互に動くようになり、音源AとBの音が同時に再生されているように聞こえるはずです。 次に、シングルスレッドのプログラム2本を同時実行する場合と、マルチスレッドのプログラム1本を走らせた場合の違いについてですが、 シングルスレッドのプログラムを同時に2本実行すると、OSはその2本のプログラムを同時に実行するため、見かけ上は、正しく作られたマルチスレッドプログラム1本を実行するのと同じ結果になります。これは、OSが、2本のプログラムをOS内部で交互に少しづつ動かすようにしているためで、そうしたOSの機能をタイムシェアリングと呼びます。ただし、OSの種類によっては、前述のようなsleep()の入っていないプログラムを実行すると、最初に起動したプログラムが制御を放棄しないので、そのプログラムだけが永久に動き続けることがあるので注意してください。永久ループする場合は、どんなOSでも、ループ中で一定時間、制御を放棄するのが常識です。 マルチスレッドプログラム1本の場合は、OSではなく、そのプログラム自身が、スレッドの切替を行う責任があります。それがsleep()の呼び出しということになります。 こんな回答で、どうでしょう?

kkkkeeennn
質問者

補足

ご丁寧にありがとうございます。 一応指摘された点を考慮してやってみたのですが上手く行きませんでした>< ナゼダロなぁ・・・OSの問題なのですかね・・・ 一応mac os x です。 >見かけ上は、正しく作られたマルチスレッドプログラム1本を実行するのと同じ結果になります 正直そこまでjavaに精通していないので僕のプログラムを説明させてもらってよいでしょうか?正しく作られていない可能性もあると思うので・・・ 音を拾って再生するスレッドをSoundとすると、 僕のmainのプログラムは main Sound sound[] = new Sound[2] sound[0]= new Sound(); sound[0].start(); --ボタンを押したら以下へ進む処理-- --ここで手動で音源を切り替えています-- sound[1]= new Sound(); sound[1].start(); となっています。 Soundの中身は run(){ --入力元を取得-- while(true){ --再生-- } } となっています・・・ メインの中でサウンドを一つだけしか走らせないものを 2回走らせればうまくは行きます。 うーーーん・・・伝わるでしょうか?

関連するQ&A