回调时的Java同步函数解锁

回调时的Java同步函数解锁,java,android,asynchronous,Java,Android,Asynchronous,我有一个类,它有一个GetTemperature()函数: 连接到设备 向设备发送读取温度的命令 读取温度时会触发回调OnGetTemperature() 在回调中,我断开了与设备的连接 此函数是从Android中的React本机应用程序调用的,可以多次调用。我无法访问React本机应用程序来限制函数调用。 问题是我想使这个函数同步。因为一次只能有一个连接处于活动状态 我试图使GetTemperature()函数同步,但该函数返回得很早,并且不等待OnGetTemperature(),因此无法工

我有一个类,它有一个
GetTemperature()
函数:

  • 连接到设备
  • 向设备发送读取温度的命令
  • 读取温度时会触发回调
    OnGetTemperature()
  • 在回调中,我断开了与设备的连接
  • 此函数是从Android中的React本机应用程序调用的,可以多次调用。我无法访问React本机应用程序来限制函数调用。 问题是我想使这个函数同步。因为一次只能有一个连接处于活动状态

    我试图使
    GetTemperature()
    函数同步,但该函数返回得很早,并且不等待
    OnGetTemperature()
    ,因此无法工作。 有没有办法锁定函数并从回调中解锁它?
    当调用
    GetTemperature()
    时,我尝试使用ReentrantLock锁定该类,并在回调中解锁它。但当回调被触发时,应用程序崩溃。可能对象已锁定,回调无法从其他线程运行?

    一个信号机将为您实现以下功能:

    public class Test {
    
    private Semaphore semaphore = new Semaphore(1); // Allow max 1 'palyer'
    
    public static void main(String[] args) {
        Test t = new Test();
        t.start(1);
        t.start(2);
        t.start(3);
        t.start(4);
    }
    
    private void start(int i) {
        try {
            semaphore.acquire();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("start " + i);
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                }
                stop(i);
            }
        };
        new Thread(runnable).start();
    }
    
    private void stop(int i) {
        System.out.println("stop " + i);
        semaphore.release();
    }
    }
    
    第一次调用
    start
    acquire将增加
    信号量的计数,然后继续(打印“start 1”等)。第二次调用
    start
    ,执行将一直保持到调用
    release
    ,这将在100毫秒后“start 1”的线程调用
    stop
    时发生

    输出将是
    start 1、stop 1、start 2、stop 2,…
    ,这是您想要的。如果移除信号量,输出将是
    start 1、start 2、start 3、start 4、stop 1、stop 2、stop 3、stop 4
    ,这是您想要的

    在您的例子中,它是一个调用
    stop
    的回调,而不是一个线程,但我相信您仍然明白我的意思


    要使解决方案完整,您需要添加一些错误处理。例如,您不能确定是否总是有回调。因此,如果
    stop
    已等待回调10秒,您可能需要从
    start
    调用。
    release

    还有一件事。。。为了100%完成错误处理,您需要为每个传入呼叫提供一个ID,当您释放信号量时,您需要检查该ID是否尚未被释放。否则这个场景就不会被处理:Call#1 to start传入,10秒后start释放信号量,Call#2传入,然后Call#1的(很晚)回调传入。在这种情况下,回调不应释放信号量,因为信号量现在“属于”call#2。OnGetTemperature有哪些参数?是否有任何对象传递给命令以读取温度?我的意思是,如何区分回调函数的不同调用?