暂停线程以获取Java中变量的值

时间:2016-05-02 12:30:14

标签: java multithreading

更新 - 我遇到了类似的帖子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; }

我们将不胜感激。

2 个答案:

答案 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}}线程有机会醒来。