Wat is de juiste manier om een ​​toepassing continu te doorlopen

Mijn vraag is niet specifiek voor Java, maar dat is de taal die ik gebruik om te bereiken wat ik wil.

Ik experimenteer met Bluetooth in Java en heb een eenvoudig terminalprogramma geschreven, d.w.z. geen GUI-interface die naar Bluetooth-apparaten in de buurt zoekt en deze opslaat. Mijn code is als volgt:

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){
    }
}

Het start-verzoek() van het DiscoveryAgent-object wordt onmiddellijk teruggezonden en alle gevonden apparaten worden teruggestuurd naar de DiscoveryListener-interface die ik heb geïmplementeerd. Het probleem is tenzij ik de while() -lus opneem, wordt het programma beëindigd voordat er apparaten worden ontdekt.

Hoe blijven applicaties efficiënt wonen? Wordt dit bereikt door een aparte 'werkende' draad en een hoofddraad te hebben die de werkdraad spawelt maar zelf slaapt totdat de werker klaar is?

0

2 antwoord

U kunt het Object wait/notify-mechanisme gebruiken om de hoofdmethode vast te houden totdat BluetoothTest op de hoogte stelt van een gemeenschappelijke objectslot.


Gewoon een pseudo-code,

Definieer een statische uiteindelijke object _mutex = new Object ();

In hoofdmethode na het aanroepen van startInquiry-oproep _mutex.wait (); Dit bevat de rode draad.

In inquiryCompleted call _mutex.notify (); Dit zal de rode draad loslaten.


Houd er rekening mee dat deze code alleen werkt als startInquiry een nieuwe thread maakt en callback-methoden oproept. Ik ben me niet zo goed bewust van de DiscoverAgent-klasse. Dus als dat niet het geval is, kan de bovenstaande oplossing nu werken.

2
toegevoegd

Java-programma's blijven actief totdat alle threads die niet als "daemon" zijn gemarkeerd worden afgesloten. Als de thread Main wordt afgesloten en er geen andere threads worden uitgevoerd, wordt het programma afgesloten. Als u een andere thread hebt voortgebracht (of als DiscoveryAgent in een andere thread wordt uitgevoerd) die geen "daemon" -thread is, blijft Java actief totdat de thread wordt afgesloten. De lus in het hoofd zetten is een prima manier om dit te doen hoewel, zoals @jatanp al zei, het gebruik van wait / notify schoner is.

Een paar dingen over uw code:

  • It is strange to have your Main code also be your DiscoveryListener. I would isolate that functionality in another class:

    public class BluetoothTest {
       ...
       private static class OurListener implements DiscoveryListener {
       }
    }
    
  • Because you have 2 threads that are reading from the same variable isAlive, it should be marked as volatile or you need to synchronize around it.
1
toegevoegd
Bedankt voor je antwoord. Toegegeven, mijn code is erg ruw en klaar en het is alleen maar testcode. Het ontstond vanwege het probleem van het voltooien van threads voordat Bluetooth-detectie was voltooid en vandaar deze vraag (om te proberen en te begrijpen hoe het correct kan worden geprogrammeerd)
toegevoegd de auteur Kerry, de bron