更新 - 我遇到了类似的帖子How to access a method from another running thread in java
但是,从代码段中提取
public void run(){
aref.setSomething();
//calling the setSomething() with this thread!!
}
但在我的情况下,aref.setSomething()永远不会运行,因为ThreadA总是很忙
美好的一天,我正在尝试用Java编写一个代码,该代码暂停一个线程足以提取Map的内容。线程启动(运行)方法时调用线程方法operateHosts。 但是我希望能够暂停该线程以允许我阅读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; }
我们将不胜感激。
答案 0 :(得分:0)
我真的建议将原子类型用于与线程控制/信令/等相关的任何。
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
希望它有所帮助。
答案 1 :(得分:0)
问题是方法
pauseRun()
永远不会运行。
它将在submitToSchedulerForMigration()
调用它时运行。但那又怎么样?它设置了一个标志,然后submitToSchedulerForMigration()
立即开始工作。与此同时,您的operateHosts()
仍在继续处理其setOfLRMs
。
设置一个标志,告诉某个线程&#34;当你这里&#34;时停止,不会停止另一个线程直到另一个线程获得*这里*
一种解决方案是为已停止的线程设置一种方法,以便在它到达停止点时进行通信,但更简单的解决方案是使用互斥(又名, 锁定)以防止两个例程同时运行。
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()
之前再次获取锁定{1}}线程有机会醒来。