2016-05-02 6 views
0

アップデートを変数の値を取得するには、スレッドを一時停止 - 私はaref.setSomethingコードスニペットは、Java

public void run(){ 
    aref.setSomething(); 
    //calling the setSomething() with this thread!! 
} 

からしかし、私の場合に抽出し、How to access a method from another running thread in java

しかし同様のポストに出くわしました( )スレッドAが常にビジーであるため実行されません

良い日、私はコードをJavaのコードを記述して、マップの内容を抽出するのに十分長いスレッドを一時停止させようとしています。 threadメソッドのoperateHostsは、スレッドが起動(実行)メソッドを呼び出すときに呼び出されます。 しかし、私は、私がマップの内容を読んで、別の方法に送信できるようにスレッドを一時停止できるようにしたい。 問題はpauseRunが実行されない方法です。デバッグモードで実行すると、ここで一時停止し、XYZスレッドを待っています。

boolean InOperatationFlag = true; 

public void run() { 

operateHosts(); } 

public synchronized void operateHosts() { 

while (InOperatationFlag) { 
int i = 0; 
     for (LRM m : setOfLRMs) { 
      System.out.println("Operating Host for thread no" + i); 
      m.runControl(); 
      i++; } 

try{ Thread.sleep(2000); } 
catch (Exception ex) { 

System.out.println ("Busy LRM was interrupted " + ex); 
ex.printStackTrace(); } 

public void pauseRun() throws InterruptedException { 
InOperatationFlag = false; } 

public void resumeRun() { 
InOperatationFlag = true; } 

public List<Map<String, Object>> submitToSchedulerForMigration() throws InterruptedException { 
pauseRun(); 

Set<? extends PowerHost> fakeHostList = new HashSet<PowerHost>(); 
    fakeHostList = mQueue.keySet(); 

List<Map<String, Object>> migMap = new LinkedList<Map<String, Object>>(); 

for (PowerHost ph : fakeHostList) { 
     migMap = this.optimizeAllocation(ph, mQueue.get(ph), exHost); } 

resumeRun(); 
    return migMap; } 

あなたのご協力をお待ちしております。

+0

Ughh!人々があなたのコードを手助けしたい場合は、コードスタイルにもっと注意を払う必要があります。コードを正しくインデントし、識別子の規則に従って、改行と空白の規則に従ってください。 –

答えて

0

私は本当にのための原子タイプの使用をお勧めしますスレッド制御/シグナリング/ etcに関連しています。

package test.thread; 

import java.util.concurrent.atomic.AtomicBoolean; 

public class Runner extends Thread{ 
    private static final boolean DEBUG = true; 

    private AtomicBoolean InOperatationFlag = new AtomicBoolean(true); 

    public void run() { 
     operateHosts(); 
    } 

    public void operateHosts() { 
     int x = 0; 
     while(true) { 
      if(InOperatationFlag.get()) { 
       int i = 0; 
       // commented out for the sake of demo 
       /* 
         for (LRM m : setOfLRMs) { 
          System.out.println("Operating Host for thread no" + i); 
          m.runControl(); 
          i++; } 
        */ 
       if(DEBUG) System.out.println("Runner: Running "+x); 
      } 
      else { 
       if(DEBUG) System.out.println("Runner: Paused "+x); 
      } 
      x++; 
      try{ Thread.currentThread().sleep(2000); } 
      catch (Exception ex) { 
       System.out.println ("Runner: Busy LRM was interrupted " + ex); 
       ex.printStackTrace(); 
      } 
     } 
    } 

    public synchronized void pauseRun() throws InterruptedException { 
     InOperatationFlag.set(false); 
    } 

    public synchronized void resumeRun() { 
    InOperatationFlag.set(true);} 

    public int submitToSchedulerForMigration() throws InterruptedException { 
     //pauseRun(); // commented out for the sake of demo 
     int ret = 12345; 
     //resumeRun(); // commented out for the sake of demo 
     return ret; 
    } 

    public static void main(String[] argc) throws Exception 
    { 
     Runner r = new Runner(); 
     if(DEBUG) System.out.println("Main: New Runner created."); 
     r.start(); 
     if(DEBUG) System.out.println("Main: Runner started."); 
     Thread.currentThread().sleep(5000); 
     if(DEBUG) System.out.println("Main: Slept 5000ms."); 
     r.pauseRun(); 
     if(DEBUG) System.out.println("Main: Pause signal sent."); 
     Thread.currentThread().sleep(5000); 
     if(DEBUG) System.out.println("Main: Slept 5000ms."); 
     System.out.println("Main: Data: "+r.submitToSchedulerForMigration()); 
     r.resumeRun(); 
     if(DEBUG) System.out.println("Main: Resume signal sent."); 
    } 
} 

結果:

Main: New Runner created. 
Main: Runner started. 
Runner: Running 0 
Runner: Running 1 
Runner: Running 2 
Main: Slept 5000ms. 
Main: Pause signal sent. 
Runner: Paused 3 
Runner: Paused 4 
Main: Slept 5000ms. 
Main: Data: 12345 
Main: Resume signal sent. 
Runner: Running 5 
Runner: Running 6 
Runner: Running 7 
Runner: Running 8 

はそれがお役に立てば幸いです。

+0

@Stephen Cは – shups

+0

と言っていますが、ThreadAとThreadBという2つのスレッドがあると仮定していただきありがとうございます。私はThreadBからThreadAのすべてのメソッドにアクセスできます。私が抱えている問題は、BからAへの一時停止信号を送信した後です。a.pauseRun()は何も起こりません.bcos ThreadAはビジー状態で応答せず、私のデバッガで「ThreadAを待っています。 Bが送信したpauseRun()が – shups

+0

@shupsに決して繋がっていない間に、whileループのwhileループで(true)、問題のコードを見ることは可能でしょうか? –

0

問題は方法pauseRun()は実行されません。

submitToSchedulerForMigration()が呼び出されたときに実行されます。しかし何?フラグを設定してからsubmitToSchedulerForMigration()すぐにが動作し始めます。一方、あなたのoperateHosts()はまだsetOfLRMsの処理に悩まされています。 *他のスレッドがここに*されるまで、他のスレッドを停止することはありません「あなたがここにを得るとき停止」にいくつかのスレッドに伝えるフラグを設定

。それが停止点に達したとき

一つの解決策は言って戻って通信する停止したスレッドのための手段を設定することですが、はるかに簡単な解決策は相互排他を使用することです(別名、をロック) 2つのルーチンが同時に実行されないようにします。

public final boolean FAIR = true; 
public final Lock lock = new ReentrantLock(FAIR); 

public synchronized void operateHosts() { 

    while (InOperatationFlag) { 
     lock.lock(); 
     try { 
      int i = 0; 
      for (LRM m : setOfLRMs) { 
       System.out.println("Operating Host for thread no" + i); 
       m.runControl(); 
       i++; 
      } 
     } finally { 
      lock.unlock(); 
     } 
    } 
} 

public List<Map<String, Object>> submitToSchedulerForMigration() throws InterruptedException { 
    lock.lock(); 
    try { 

     Set<? extends PowerHost> fakeHostList = new HashSet<PowerHost>(); 
     fakeHostList = mQueue.keySet(); 

     List<Map<String, Object>> migMap = new LinkedList<Map<String, Object>>(); 

     for (PowerHost ph : fakeHostList) { 
      migMap = this.optimizeAllocation(ph, mQueue.get(ph), exHost); 
     } 

    } finally { 
     lock.unlock(); 
    } 

    return migMap; 
} 

注:私はここ​​ブロックの代わりに、Lockオブジェクトを使用することもできましたが、ReentrantLockクラスが公正と呼ばれる便利な機能を実装しています。

公平性submitToSchedulerForMigration()スレッドがロックを獲得するために待機しているとき、operateHosts()はロックを解除した後、周りのループとsubmitToSchedulerForMigration()スレッドが目を覚ますする機会を持って前に再びそれをつかむことができないことを意味します。