什么是持续循环应用程序的正确方法?



我的问题不是特定于Java,但这是我用来实现我想要的语言。

我在Java中尝试蓝牙,并编写了一个简单的终端程序,即没有GUI界面,搜索附近的蓝牙设备并列出它们。我的代码如下:

import javax.bluetooth.*;
public class BluetoothTest implements DiscoveryListener{
    private static boolean isAlive = true;
    public static void main(String[] args) {
        try {
            LocalDevice ld = LocalDevice.getLocalDevice();
            if (LocalDevice.isPowerOn()){
                System.out.println("Power On.");
                System.out.println("Friendly Name: " + ld.getFriendlyName());
                System.out.println("Address: " + ld.getBluetoothAddress());
                DiscoveryAgent da = ld.getDiscoveryAgent();
                da.startInquiry(DiscoveryAgent.GIAC,new BluetoothTest());
                while (isAlive){
                    /* Sleep */
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            } else {
                System.out.println("Power Off.");
            }
        } catch (BluetoothStateException e) {
            System.out.println(e.toString());
        }
    }
    public void setAlive(boolean status){
        isAlive = status;
    }
    public void deviceDiscovered(RemoteDevice rd, DeviceClass dc){
        try{
            System.out.println(rd.getFriendlyName(true));
        } catch (java.io.IOException e){
            System.out.println(e.toString());
        }
    }
    public void inquiryCompleted(int discType){
        isAlive = false;
    }
    public void servicesDiscovered(int transID, ServiceRecord[] sr){
    }
    public void serviceSearchCompleted(int transID, int respCode){
    }
}

DiscoveryAgent对象的startinquery()立即返回,任何被发现的设备都返回到我已经实现的DiscoveryListener接口。问题是,除非我包含while()循环,否则程序将在发现任何设备之前终止。

应用程序如何有效地保持驻留?它是通过有一个单独的"工作"线程和主线程产生工作线程,但自己睡觉,直到工人已经完成?

你可以使用Object wait/notify机制来保持main方法直到BluetoothTest通知一个公共对象锁。


只是一个伪代码,

定义一个静态final对象_mutex = new Object();

在调用startinquery后调用_mutex.wait();这将占用主线程。

In inquiryCompleted call _mutex.notify();这会释放主线程。


请注意,只有当startinquery创建一个新线程并调用回调方法时,这段代码才会工作。我不太了解DiscoverAgent类。因此,如果不是这种情况,上面的解决方案现在可能工作。

Java程序将一直运行,直到所有未标记为"守护进程"的线程退出。如果Main线程退出并且没有其他线程运行,则程序将退出。如果生成了另一个不是"守护"线程的线程(或者DiscoveryAgent在另一个线程中运行),那么Java将继续运行,直到该线程退出。将循环置于main中是一种很好的方法,尽管正如@jatanp所提到的,使用wait/notify更干净。

关于代码的几点注意事项:

  • 这是奇怪的有你的主代码也是你的DiscoveryListener。我将把这个功能隔离在另一个类中:

    public class BluetoothTest {
       ...
       private static class OurListener implements DiscoveryListener {
       }
    }
    
  • 因为你有2个线程正在从同一个变量isAlive中读取,它应该被标记为volatile,或者你需要在它周围synchronize

最新更新