簡體   English   中英

暫停線程以獲取Java中變量的值

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM