EDIT:私はInheritableThreadLocal
を使用するように私のオリジナルの提案(下記)からの私の例のコードを修正し、私はそう更新されたコードを追加し、それははるかに簡単であることがわかりました。ここで
更新ThreadLocalManagerです:
package inheritableThreadLocal;
public class ThreadLocalManager {
public static final InheritableThreadLocal<String> accountUsername = new InheritableThreadLocal<String>();
public static final InheritableThreadLocal<String> accountPassword = new InheritableThreadLocal<String>();
public static final InheritableThreadLocal<Long> accountId = new InheritableThreadLocal<Long>();
}
私もRunner
を更新(以下、オリジナルを参照)が、今、その唯一の目的は、変数の値を印刷することである。
package inheritableThreadLocal;
public class Runner implements Runnable{
@Override
public void run() {
System.out.println("Inside Runner's run");
System.out.println(ThreadLocalManager.accountId.get());
System.out.println(ThreadLocalManager.accountUsername.get());
System.out.println(ThreadLocalManager.accountPassword.get());
}
}
が最後に更新メインメソッドを含むクラス:
package inheritableThreadLocal;
public class ThreadLocalMain {
public static void main(String[] args) {
System.out.println("At start of main");
System.out.println(ThreadLocalManager.accountId.get());
System.out.println(ThreadLocalManager.accountUsername.get());
System.out.println(ThreadLocalManager.accountPassword.get());
Thread t1 = new Thread(new Runnable(){
@Override
public void run() {
ThreadLocalManager.accountId.set(new Long(12345));
ThreadLocalManager.accountUsername.set("user1");
ThreadLocalManager.accountPassword.set("pass1");
System.out.println("In t1 run");
System.out.println(ThreadLocalManager.accountId.get());
System.out.println(ThreadLocalManager.accountUsername.get());
System.out.println(ThreadLocalManager.accountPassword.get());
Thread t2 = new Thread(new Runner());
t2.start();
}
});
t1.start();
}
}
オリジナルの提案:
Runnable
オブジェクトを使用して、新しいThread
オブジェクトを作成することができます。これを行うと、Runnable
を実装するカスタムオブジェクトを作成し、新しいThread
が開始されるまでThreadLocal
変数の値を保持できます。新しいThread
が開始されると(run
メソッドが呼び出されます)、これらのカスタムRunnable
オブジェクトはThreadLocal
という変数を設定します。完全のために
package threadLocal;
public class ThreadLocalMain {
public static void main(String[] args) {
System.out.println("At start of main");
System.out.println(ThreadLocalManager.accountId.get());
System.out.println(ThreadLocalManager.accountUsername.get());
System.out.println(ThreadLocalManager.accountPassword.get());
Thread t1 = new Thread(new Runnable(){
@Override
public void run() {
ThreadLocalManager.accountId.set(new Long(12345));
ThreadLocalManager.accountUsername.set("user1");
ThreadLocalManager.accountPassword.set("pass1");
System.out.println("In t1 run");
System.out.println(ThreadLocalManager.accountId.get());
System.out.println(ThreadLocalManager.accountUsername.get());
System.out.println(ThreadLocalManager.accountPassword.get());
Thread t2 = new Thread(new Runner(ThreadLocalManager.accountUsername.get(),
ThreadLocalManager.accountPassword.get(),
ThreadLocalManager.accountId.get()));
t2.start();
}
});
t1.start();
}
}
が、ここで私が使用しThreadLocalManagerです:
は、ここで私はこのために作成し、メインとクラスの
:
package threadLocal;
public class ThreadLocalManager {
public static final ThreadLocal<String> accountUsername = new ThreadLocal<String>();
public static final ThreadLocal<String> accountPassword = new ThreadLocal<String>();
public static final ThreadLocal<Long> accountId = new ThreadLocal<Long>();
}
最後に、ここで私が作成したカスタムRunnable
です
package threadLocal;
public class Runner implements Runnable{
private String userName, password;
private long acctId;
public Runner(String user, String pword, long accountId){
System.out.println("In Runner constructor");
System.out.println(ThreadLocalManager.accountId.get());
System.out.println(ThreadLocalManager.accountUsername.get());
System.out.println(ThreadLocalManager.accountPassword.get());
userName = user;
password = pword;
acctId = accountId;
}
@Override
public void run() {
System.out.println("Inside Runner's run");
System.out.println(ThreadLocalManager.accountId.get());
System.out.println(ThreadLocalManager.accountUsername.get());
System.out.println(ThreadLocalManager.accountPassword.get());
ThreadLocalManager.accountId.set(acctId);
ThreadLocalManager.accountUsername.set(userName);
ThreadLocalManager.accountPassword.set(password);
System.out.println("Inside Runner's run - after setting");
System.out.println(ThreadLocalManager.accountId.get());
System.out.println(ThreadLocalManager.accountUsername.get());
System.out.println(ThreadLocalManager.accountPassword.get());
}
}
このコードでは、ThreadLocal
個の変数をRunner
インスタンスに追加し、次にRunner
インスタンスを使用して新しいThread
を作成します(このコードを実行すると、最初にThreadLocal
変数の値はありません)。そして、Runner
はThreadLocal
の変数を設定し、コンソール出力から見ることができるように、それらはt1のものと一致します。
希望すると便利です。
'ThreadLocal'を別のスレッドに渡すことに意味はありません。実際の値を渡す必要があります。 – shmosel
InheritableThreadLocalが必要なのでしょうか? https://docs.oracle.com/javase/7/docs/api/java/lang/InheritableThreadLocal.html – tsolakp
@tsolakp初めて、私はそれを見つけました。 – shmosel