2016-12-09 6 views
1

私はスレッドを学んでいます。学習中に、静的変数が2つのスレッドによって使用されるシナリオを見つけました。クラスのメンバ変数を同期する

2つのスレッド間の同期動作が必要です。ここで

が私のコードです:

package com.learning.fizzbuzz; 

public class Trigger { 

    public static void main(String[] args) { 

     Solution s = new Solution("thread1"); 
     s.start(20); 

     Solution s1 = new Solution("thread2"); 
     s1.start(15); 

    } 

} 

package com.learning.fizzbuzz; 

import java.util.ArrayList; 
import java.util.List; 

public class Solution implements Runnable{ 

    private Thread t; 

    private String threadName; 

    private static int n; 

    public Solution(String threadName) { 
     this.threadName = threadName; 
     System.out.println("Creating thread :: "+ threadName); 
    } 

    public static List<String> fizzBuzz(int n) { 

     List<String> elements = new ArrayList<>(); 

     for (int i = 1; i <= n; i++) { 
      if (i % (15) == 0) { 
       elements.add("FizzBuzz"); 
      } 
      else if (i % 3 == 0) { 
       elements.add("Fizz"); 
      } 
      else if (i % 5 == 0) { 
       elements.add("Buzz"); 
      } 
      else { 
       elements.add(String.valueOf(i)); 
      } 
     } 

     return elements; 
    } 

    public static String reverseString(String s) { 
     StringBuffer str = new StringBuffer(s); 
     s = str.reverse().toString(); 
     return s; 
    } 

    @Override 
    public synchronized void run() { 
      System.out.println("Executing thread :: " + threadName); 
      List<String> str = fizzBuzz(n); 
      System.out.println(str +" :: "+ t.getName()); 
      System.out.println(reverseString("Hello") +" :: "+ t.getName()); 
    } 

    public void start(int num) { 
     if (t == null) { 
      System.out.println("Starting thread :: " + threadName); 
      t = new Thread(this, threadName); 
      Solution.n = num; 
      System.out.println("number is " + n); 
      t.start(); 
     } else { 
      System.out.println("Thread Already Created and Running :: " + threadName); 
     } 
    } 
} 

私は、ソリューションのクラスの様々なブロックを同期しようとしたが、後述するように結果を得ることができませんでした。

[1、2、フィズ、4、バズ、フィズ、7、8、フィズ、バズ、11、フィズ、13、14、 FizzBu​​zz、16、17、フィズ、19、バズ] ::スレッド2 olleH ::スレッド2

[1、2、フィズ、4、バズ、フィズ、7、8、フィズ、バズ、11、フィズ、13、14、 FizzBu​​zz] ::スレッド1 olleH ::スレッド1

ご連絡ください。

EDIT:両方のスレッドが実行を開始する前に、nの値が15に設定されていることがわかりました。それを避ける方法は?

+0

正確にどのような動作が必要ですか? – Sentry

+0

最初のスレッドは20個の要素を配列で出力する必要があります。 2番目のスレッドは15個の要素を配列で出力する必要があります。 –

+0

インスタンス変数を使用してその結果を取得する必要があります。 – Bubletan

答えて

0

静的共有変数にアクセスするには、同じモニター上の2つ(またはそれ以上)のスレッドを同期させる必要があります。

変数thisで同期するため、メソッドインスタンスでキーワード​​を使用することはできません。

最も簡単な方法は、静的変数を使用して同期することです。

public class MyClass { 
    private static Object lock = new Object(); 

    private static int sharedVariable; 

    public void yourMethod() { 

     synchronized(lock) { 
      // Do something with sharedVariable 
     } 
    } 

} 
+0

これを試してみてください。うまく行かなかった。 –

+0

これはうまくやっているようではありません。ここでの「同期」とは、同期ブロック内にコードを入力して実行できるスレッドが1つだけであることを意味します。しかし、これを行っても、2つの別々の値を保持する変数が1つあります。 – Sentry

関連する問題