倾听数据,是(真)正确的解决方案吗? Java的

时间:2015-04-13 13:00:22

标签: java while-loop

我遇到了一个问题,我希望有人可以帮助我。现在,我在我的程序中使用了太多而(真)循环的方式,因此运行速度有点慢。

我不确定我的代码是否有问题,或者这是否是唯一的解决方案。

有一个从另一个班级接收数据(双打)的班级。想要启动一个while循环,它只在数据不是0时运行。我在这里有一些代码:

while (true) {
        while (kWh != 0) {
            try {
                queue.put(kWh);
            } catch (InterruptedException e) {                  
                System.out.println("Could not put data into queue");
            }
            kWh = 0;
        }   
    }





@Override
public void SendPower(double power_data) throws RemoteException {
    ReceivePowerData.kWh = power_data;              
}

如您所见,当SendPower方法运行时,kWh变量会更新。当此变量不为0时,我希望运行while循环并将值插入队列。我的问题是我正在使用while(true)所以它继续运行该循环,即使没有收到数据,这也是一种浪费。

我还能做什么?任何想法?

更新

我试过使用wait();方法,似乎工作,它等待..但我不知道我应该如何实现notify();应该重新开始的方法。

代码:

synchronized (this) {
        System.out.println("Wait for response from sensor");
        try {
            wait();
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
        System.out.println("Continue");

        while (kWh != 0) {
            try {
                queue.put(kWh);
            } catch (InterruptedException e) {                  
                System.out.println("Could not put data into queue");
            }
            kWh = 0;
        }   

    }

然后我尝试在方法中对其进行编码,但我认为这是错误的。

@Override
public void SendPower(double power_data) throws RemoteException {
    ReceivePowerData.kWh = power_data;  

    synchronized (this) {
        notify();   
    }

}

所以当从另一个程序调用SendPower方法时,它应该运行,然后它应该启动,但这不起作用..我是否关闭?

3 个答案:

答案 0 :(得分:5)

您可以使用观察者模式。 Java具有实现它的标准接口。

Java中有关于此模式的大量教程

http://en.wikipedia.org/wiki/Observer_pattern http://www.tutorialspoint.com/design_pattern/observer_pattern.htm

这是一个非常简单的例子。

import java.util.Observable;
import java.util.Observer;
import java.util.Random;

public class ObserverPattern {
    private static class PowerObserverable extends Observable implements Runnable {

        public void run() {
            Random random = new Random();
            for (int x = 0; x < 10; x++) {
                double kwh = random.nextDouble() * 4;
                setChanged();
                notifyObservers(kwh);
            }
        }
    }

    // Make sure this class is thread safe
    private static class PowerObserver implements Observer {
        @Override
        public void update(Observable o, Object kwh) {
            System.out.println(kwh);
        }
    }

    public static void main(String[] args) {
        PowerObserverable observerable = new PowerObserverable();
        observerable.addObserver(new PowerObserver());

        new Thread(observerable).start();
    }
}

答案 1 :(得分:0)

您也可以使用此处描述的中断睡眠Interrupt a sleeping thread

http://www.javamex.com/tutorials/threads/thread_interruption.shtml http://www.java2s.com/Code/Java/Threads/Threadsleepandinterrupt.htm

正如您所看到的,活动池循环始终是最糟糕的解决方案。

答案 2 :(得分:0)

使用Guarded Method

请注意,该队列仅在synchronized方法中访问,因此不需要是同步队列。

private final Queue<Integer> queue = ArrayDeque<Integer>();

public synchronized void addKWh(int kwh){
   queue.put(kWh);
   notifyAll(); //tell other thread queue has something
}

//running on other thread
public synchronized void efficientQueueProcessor() { 
    while (true) { //really should have an exit condition
        Integer kwh = null;
        synchronized { //mainly because wait() must be in sync, but also for queue
            Integer kwh = queue.poll();
            if (kwh == null) {
              //queue is empty
              wait(); //thread will wait here efficiently until something is added
              continue; //so null is not processed
            }
        }
        processFigure(kwh); // out of sync block
    }
}

public void processFigure(int kwh){
    // do work with kwh
}

调用要添加的方法,设置公共字段是不好的形式:

@Override
public void SendPower(double power_data) throws RemoteException {
    ReceivePowerData.addKWh(power_data);
}