[英]Pausing a thread to get the value of a variable in Java
更新-我遇到了類似的帖子如何從Java中的另一個運行線程訪問方法
但是,從代碼片段中提取
public void run(){
aref.setSomething();
//calling the setSomething() with this thread!!
}
但是在我的情況下aref.setSomething()永遠不會運行,因為ThreadA總是很忙
美好的一天,我正在嘗試用Java編寫代碼,以使線程暫停足夠長的時間以提取Map的內容。 當線程啟動(運行)方法時,將調用線程方法operaHosts。 但是我希望能夠暫停線程以允許我讀取Map的內容並發送給其他方法。 問題是方法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; }
您的幫助將不勝感激。
我真的建議將Atomic類型用於與線程控制/信號發送/等等相關的任何事情 。
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
希望能幫助到你。
問題是方法
pauseRun()
永遠不會運行。
它會在submitToSchedulerForMigration()
調用時運行。 但是那又怎樣呢? 它設置一個標志,然后submitToSchedulerForMigration()
立即開始工作。 同時,您的operateHosts()
仍在處理其setOfLRMs
。
設置一個標志,告訴某個線程“到達這里時停止”, 直到另一個線程到達* here * ,才停止另一個線程。
一種解決方案是為被停止的線程建立一種通信方式,使其在到達停止點時可以說回,但更簡單的解決方案是使用互斥 (aka, locking )來防止兩個例程在同一時間。
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;
}
注意:我可以在這里使用synchronized
塊而不是Lock
對象,但是ReentrantLock
類實現了一個稱為fairness的有用功能。
公平性意味着,當submitToSchedulerForMigration()
線程正等待獲取該鎖時, operateHosts()
將無法釋放該鎖,然后在submitToSchedulerForMigration()
線程有機會喚醒之前環回並再次獲取它。 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.