什么是连续循环应用的正确方法

时间:2011-12-06 20:02:59

标签: java bluetooth

我的问题不是特定于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对象的startInquiry()立即返回,并且发现的所有设备都将返回到我已实现的DiscoveryListener接口。问题是除非我包含while()循环,程序将在发现任何设备之前终止。

应用程序如何有效地驻留?它是通过一个单独的“工作”线程和一个主线程来实现的,它产生了工作线程,但它自己会一直睡到工人完成之前?

2 个答案:

答案 0 :(得分:2)

您可以使用对象等待/通知机制来保存main方法,直到BluetoothTest通知公共对象锁。


只是一个伪代码,

定义静态最终对象_mutex = new Object();

调用startInquiry后调用_mutex.wait();这将成为主线。

在inquiryCompleted中调用_mutex.notify();这将释放主线程。


请注意,只有在startInquiry创建新线程并调用回调方法时,此代码才有效。我不太了解DiscoverAgent课程。因此,如果情况并非如此,则上述解决方案现在可以正常工作。

答案 1 :(得分:1)

Java程序将保持运行,直到所有未标记为“守护程序”的线程退出。如果Main线程退出并且没有其他线程在运行,则程序将退出。如果你产生了另一个线程(或者如果DiscoveryAgent正在另一个线程中运行)而不是“守护进程”线程,那么Java将一直运行直到线程退出。将循环放在main中是一种很好的方法,尽管如@jatanp所述,使用wait / notify更清晰。

关于代码的一些事情:

  • 让您的主要代码也是您的DiscoveryListener很奇怪。我会在另一个类中隔离该功能:

    public class BluetoothTest {
       ...
       private static class OurListener implements DiscoveryListener {
       }
    }
    
  • 由于您有2个线程正在从同一个变量isAlive中读取,因此应将其标记为volatile,或者您需要synchronize围绕它。