2017-04-18 5 views
1

私は2つのスレッドを持っています。最初は変数データの値を変更します。 2番目の値は、値が変更されている場合は値を出力します。変数の値が変更されるたびに2番目のスレッドを印刷しようとしていますが、成功しません。誰かが私を助けることができますか?変数の変更の2番目のスレッドに通知する方法

スレッド1

class someservice{ 

    volatile int data; 
    Boolean Flag = false; 

    public void mymethod(){ 

     flag = true; 

     for (Integer i = 1; i < sheet.getRows(); i++) { 

      data = someMethod(); //this method when called return a new 
            //value 
     } 

     flag = false; 
     ... 
    } 
    } 

スレッド2

Promise p = task { 
      try { 

       while (true) { 

        if (engineService.getFlag()) { 

          print(someservice.data);        

        }else{ 
         break; 
        } 
       } 
      } catch(Throwable t) { 
       ... 
      } 
     } 
+0

あなたは 'true'に' engineService.getFlagを() 'に設定されていますか?私はあなたのコードでそれを見ることはありません... – brso05

+0

正しい軌道に乗っています...代わりに約束するコール可能な、将来の... –

答えて

0

あなたが約束を言及しているので、私はあなたがJavaで+ C++ 11

における将来/約束に精通している推測同じようなアプローチがあり、将来呼び出すことができます...

public class HW5 { 
    public static void main(String[] argv) throws InterruptedException, ExecutionException { 
    FutureTask<Boolean> myFutureTask = new FutureTask<>(new Callable<Boolean>() { 

     @Override 
     public Boolean call() throws Exception { 
     // implement the logic here and return true if everything was 
     // ok, false otherwise. 
     Thread.sleep(5000); 
     System.out.println("dddd"); 
     return System.currentTimeMillis() % 2 == 0; 
     } 
    }); 

    ExecutorService executor = Executors.newFixedThreadPool(1); 
    executor.execute(myFutureTask); 
    Boolean result = myFutureTask.get(); 
    System.out.println("Done!"); 
    } 
} 

Futureジョブが終了した後にObjectを返すことのできる呼び出し可能なクラスのタスク... Futureタスクを実行するには、Executorサービスを使用することができます。その後、仕事をするためのスレッドの..あなただけの変数結果を読み、その結果を検証するために、基本的にブロックが将来までメインスレッドが実行されますFuture.getを呼び出すことが必要である

0

あなたはスレッド内でnotify()とnotifyAll()メソッドを使うことができます。このリンクをチェックアウト:https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html

public synchronized void guardedJoy() { 
    // This guard only loops once for each special event, which may not 
    // be the event we're waiting for. 
    while(!joy) { 
     try { 
      wait(); 
     } catch (InterruptedException e) {} 
    } 
    System.out.println("Joy and efficiency have been achieved!"); 
} 


public synchronized notifyJoy() { 
    joy = true; 
    notifyAll(); 
} 
+0

空のキャッチブロックを書いてはいけません。また、InterruptedExceptionを無視しないでください。割り込みとは、別のスレッドからの明示的な要求であり、あなたがやっていることを止めて正常に終了することです。それを無視すると、あなたのコードは不正なスレッドになります。 – VGR

+0

合意。これは、私が参照しているOracleのリンクからのスニペットです。私は彼/彼女がコードを逐語的に使用するとは思わない。 :) – Matt

0

あなたは並行プログラミングに関するより多くのデータを検索する必要があるが、私はないので、基本的な、まあ、今いくつかの基本をあなたに伝えることができますが、私は自分のベストを尽くします。

ここでは、モニターを持っている、それは抽象的な概念であり、履歴書には、モニターがすべてと クラスであり、それは、それは、唯一 つのスレッド が メソッドにアクセスすることができ を修飾子として「syncronized」 を使用して 方法を意味しています すぐに。so、モニターでは、 印刷したい 変数 で と「フラグ」、 わかりますその 変数 がmodified.Finally、 た場合は 、 最も重要なことを見ることができます"wait()"と "notify()"のメソッド これらのメソッド は、スレッドを停止するか、または のスレッドをもう一度再生します。あなたの変数が変更された場合

あなたは

printValue()メソッドでは、ここで を尋ね、変数was'nt変更した場合は、待機()メソッドと一緒に寝てthead要素を入れて、そしてときに、他の

方法changeValue()が実行され、値が変更され、通知()メソッドは、スレッドを目覚め、と呼ばれる、そう、このすべてをやっている、あなたは、三つのことを保証することができます

安全性:ことを意味しますスレッドはあなたが望むことを実行します デッドロックの不在:将来は目が覚めるでしょう。 ミューテックス:重要なコードを実行しているスレッドが1つだけであることを意味します(例:op。 "++"はアトミックではありませんが、より多くのアクションで細分化され、ローカルvarを作成し、var、sum、およびasignを読み込みます。したがって、複数のスレッドがゲーム内にある場合、例:複数のスレッドが実行しているため、次のコードで起こるそうであっても起こり、そして可能性

i = 0; 
i ++; 
output: 1; 
output: 2; 
output: 3; 
output: 5; 
output: 4; 
output: 7; 

、。あなたが注文したい場合は

public class BClass extends Thread{ 

     private Monitor ac; 

     public BClass(Monitor ac) { 
      this.ac = ac; 
     } 

     @Override 
     public void run() { 
      int v = 0; 
      while(true){ 
       this.ac.changeValue(v); 
       v++; // this sum is not secure, if you want to print an 
        // ascending order, the code is diferent, I will show in 
        // above. 
      } 
     } 

、今:ついに

public class AClass extends Thread{ 

     private Monitor ac; 

     public AClass(Monitor ac) { 
      this.ac = ac; 
     } 

     @Override 
     public void run() { 
      while(true){ 
       this.ac.printValue(); 
      } 
     } 

    } 

そして:まあ、これは複数のスレッド、多かれ少なかれ今

public class Monitor { 

     private int value = 0; 
     public static boolean valueHasChanged = false; 

     public synchronized int changeValue(int newValue){ 
      this.value = newValue; 
      Monitor.valueHasChanged = true; 
      this.notify(); 
      return this.value + 1; 
     } 

     public synchronized void printValue(){ 
      while(!Monitor.valueHasChanged){ 
       try { 
        this.wait(); 
       } catch (InterruptedException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
      System.out.println(this.value); 
      Monitor.valueHasChanged = false; 
     } 

     public static void main(String[] args) { 
      Monitor ac = new Monitor(); 

      BClass t1 = new BClass(ac); 
      AClass t2 = new AClass(ac); 

      t1.start(); 
      t2.start(); 
     } 

     public int getValue() { 
      return this.value; 
     } 
    } 

スレッドをプログラムする方法があります表示:

public class Monitor { 

     private int value = 0; 
     public boolean valueHasChanged = false; 
     private boolean hasPrint = true; 

     public synchronized void changeValue(int newValue) { 
      this.value = newValue; 
      this.valueHasChanged = true; 
      this.notify(); 
     } 

     public synchronized void changeValuePlusOne() { 
      while (!hasPrint) { 
       try { 
        this.wait(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
      this.value++; 
      this.valueHasChanged = true; 
      this.hasPrint = false; 
      this.notifyAll(); 
     } 

     public synchronized void printValue() { 
      while (!this.valueHasChanged) { 
       try { 
        this.wait(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
      System.out.println(this.value); 

      this.valueHasChanged = false; 
      this.hasPrint = true; 
      this.notifyAll(); 
     } 

     public static void main(String[] args) { 
      Monitor ac = new Monitor(); 

      BClass t1 = new BClass(ac); 
      AClass t2 = new AClass(ac); 

      t1.start(); 
      t2.start(); 
     } 

     public int getValue() { 
      return this.value; 
     } 

    } 

とスレッド:

public class BClass extends Thread{ 

     private Monitor ac; 

     public BClass(Monitor ac) { 
      this.ac = ac; 
     } 

     @Override 
     public void run() { 
      while(true){ 
       this.ac.changeValuePlusOne(); 
      } 
     } 

     } 

他のスレッドを見に等しい:あなたは、変数を変更したとき

public class AClass extends Thread{ 

    private Monitor ac; 

    public AClass(Monitor ac) { 
     this.ac = ac; 
    } 

    @Override 
    public void run() { 
     while(true){ 
      this.ac.printValue(); 
     } 
    } 

} 
関連する問題