2017-11-08 1 views
1

私はJavaプログラムinorder内でThreadLocalを使用して、特定のデータメンバーをスレッドから取得して設定しています。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>(); 
    ..................... 
    ..................... 
    ..................... 

} 

を持つクラスを持っています。今度は各スレッドが別のスレッドを作成していて、作成した新しいスレッドにThreadLocalManagerを渡します。これはどのようにして行われますか?

+3

'ThreadLocal'を別のスレッドに渡すことに意味はありません。実際の値を渡す必要があります。 – shmosel

+3

InheritableThreadLocalが必要なのでしょうか? https://docs.oracle.com/javase/7/docs/api/java/lang/InheritableThreadLocal.html – tsolakp

+0

@tsolakp初めて、私はそれを見つけました。 – shmosel

答えて

1

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変数の値はありません)。そして、RunnerThreadLocalの変数を設定し、コンソール出力から見ることができるように、それらはt1のものと一致します。

希望すると便利です。

関連する問題