如何通知第二个线程变量的变化

问题描述:

我有两个线程。第一个更改变量Data的值。如果它的值已经改变,第二个打印值。我试图做的第二个线程只是打印每次该变量的值改变,但我没有达到成功。有人可以帮助我吗?如何通知第二个线程变量的变化

线程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

当您更改变量你设置'engineService.getFlag()''到TRUE'?我没有在你的代码中看到它... – brso05

+0

你是在正确的轨道上...而是承诺使用可调用的,未来... –

既然你提到的承诺,我推断你所熟悉的未来/承诺在+ C++ 11

在Java有一个类似的方法,未来可以调用...

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!"); 
    } 
} 

FutureTask中的一个类需要一个可调用的对象,可以在其作业完成后返回一个对象...为了执行Future任务,您可以使用Executor服务,特别是调用方法execute,因为您需要等待该线程来完成这项工作,然后是必要的,你叫的Future.get,将基本块主线程等到将来完成,以验证结果,刚读变量结果 ..

你可以在线程中使用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

不要写空的catch块。并且不要忽略InterruptedException;中断是来自另一个线程的显式请求,用于停止正在执行的操作并正常退出。忽略它会使您的代码成为流氓线程。 – VGR

+0

同意。这是我引用的Oracle链接的一个片段。我认为他/她不会逐字使用代码。 :) – Matt

你要查找有关并发编程更多的数据,我可以告诉你,现在的一些基础知识,好了,不那么这样基本的,但我会尽我所能:

在这里,你有一个监视器,它是一个抽象的概念,在简历中,监视器是一个 类与所有它的使用 法“syncronized” 作为改性剂,它意味着, 只有 一个线程 可以访问 方法 一次。因此, 在 显示器 变量 你 要打印, 并告诉你,如果 变量 是modified.Finally, 可以 看到 最重要的事情“标志”, 时, “等待()”和“通知()”方法, 那些方法 停止线程,或“播放” 他们再次。

您在

的PRINTVALUE()方法在这里问 ,如果您的变量被改变,如果变量was'nt变化,把THEAD与wait()方法来睡觉,而当其他

方法changeValue()被执行时,值被修改,和notify()方法被调用时,唤醒线程,因此,做这一切,你能保证三两件事:

安全性:这意味着线程将完成你想要的操作 没有死锁:意味着被放置的线程睡觉,将来会清醒。 互斥体:意味着只有一个线程正在执行关键代码,例如,操作。 “++”不是原子的,被细分为更多的一个动作,创建一个局部变量,读取var,sum和asign,所以,如果多于一个线程在游戏中,则该值可能不是连续的,例如:

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

可能发生,即使如此,因为有一个以上的线程中执行,这将在未来的代码发生。那么,这是有几个线程,或多或少

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 AClass extends Thread{ 

     private Monitor ac; 

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

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

    } 

最后:

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 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(); 
     } 
    } 

}