親スレッド (メイン/UI スレッド) から子スレッドを開始しました。そして、この子スレッドから別のスレッド (孫?) を開始します。ここで、メイン スレッドから孫スレッドに文字列を渡して、この文字列を使用して孫スレッドでメソッドを呼び出せるようにしたいと考えています。
私はJavaとスレッドが初めてなので、これは私を混乱させます。メッセージハンドラーなどを見てきましたが、理解できる例が見つからないため、それが正しい方法であるかどうかはわかりません。
親スレッド (メイン/UI スレッド) から子スレッドを開始しました。そして、この子スレッドから別のスレッド (孫?) を開始します。ここで、メイン スレッドから孫スレッドに文字列を渡して、この文字列を使用して孫スレッドでメソッドを呼び出せるようにしたいと考えています。
私はJavaとスレッドが初めてなので、これは私を混乱させます。メッセージハンドラーなどを見てきましたが、理解できる例が見つからないため、それが正しい方法であるかどうかはわかりません。
通常、Java のスレッド間で値を渡すことはありませんし、渡すこともできません。スレッド間で値とオブジェクトを共有します。スレッド間での値の共有と受け渡しには、非常に微妙な違いがあります。なんらかの方法でスレッドに値を渡すと、そのスレッドはそれに対する排他的権利を持ちます。つまり、スレッドは独自の値のコピーを持ち、同期されていないコードやその変数のスレッド セーフについて心配する必要はありません。通常、このタイプの概念は、メッセージ パッシングを使用する並行システムで使用されます。参照してください: https://en.wikipedia.org/wiki/Message_passing
しかし、Java では通常、複数のスレッド間で値を共有します。また、スレッド間に関係はありません。つまり、子スレッドや孫スレッドはありません。デーモン スレッドと非デーモン スレッドのみがあります ( http://www.javaworld.com/jw-04-1996/jw-04-threads.html )。したがって、孫とメインスレッドの間で値を共有する必要がある場合。それらの間で利用可能/共有できる単一のオブジェクトを作成する必要があります。以下の例を参照してください。
public class GranDChildThread {
/**
* Please note there are no relation ships among thread.
* Simply put, a thread is a program's path of execution.
* All the three threads have access to shared String
*/
public static String sharedString = new String("its a wonderfull life");
public static void main(String[] args) {
// this is my main Thread
System.out.println("Main Thread: I have access to
sharedString : " + sharedString);
Thread childThread = new Thread(new Runnable() {
@Override
public void run() {
// this is child thread
System.out.println("Child Thread:
I have access to sharedString : " + sharedString);
Thread grandChildThread = new Thread(new Runnable() {
@Override
public void run() {
// this grand Child
System.out.println("Grand Child Thread:
I have access to sharedString : " + sharedString);
}
});
}
});
}
}
これが最も簡単な例です。セッターとゲッターを使用すると便利です。
import android.os.Bundle;
import android.util.Log;
public class MyExtendedThread extends Thread{
private String mData;
public MyExtendedThread(String dataStringIwantToPass){
this.mData = dataStringIwantToPass;
}
@Override
public void run() {
//DO SOMETHING WITH mData
//for example:
while(true){
if(mData != null)
Log.i("mData: ", mData);
Thread.sleep(2000);//sleep it few seconds :)
}
}
public String getData() {
return mData;
}
public void setData(String mData) {
this.mData = mData; //you might want to change the value at some point of time
}
}
ここで Thread クラスを、セッターとゲッター、および引数付きコンストラクターを持つカスタム クラスに継承します。それはかなり簡単です。セッターを使用して、必要なときにいつでも文字列の値を変更します。
@Override
public void onCreate(Bundle savedInstanceState ) {
final String data = "this is string";
Thread theThreadStartedFromUIthread = new Thread(new Runnable(){
MyExtendedThread myOtherThread = new MyExtendedThread(data);
@Override
public void run() {
// Do some stuff
myOtherThread.start();// the other (grandchild) thread has started
//here i want to change the value of mData, assuming the thread is still running
myOtherThread.setData("Alright, I've changed you.");
}});
};
}
それは役に立ちますか?