是什么使异步单线程java代码异步



因此,我们目前正在开发一款java应用程序,一位同事向我介绍了异步编程,无论我研究了多少,对我来说,这似乎是同步的。因此,异步代码的主要优点似乎是不冻结UI,而某些操作需要很长时间才能执行并返回结果,我们所需要做的就是给该函数一个回调函数,该函数将在作业完成时调用。根据我从网上来源和stackoverflow上的类似问题了解到,代码可以是单线程和异步的,有人甚至把它画成这样:

异步(一个线程)(来源:异步与同步执行,它的真正含义是什么?):

A-Start ------------------------------------------ A-End   
| B-Start -----------------------------------------|--- B-End   
|    |      C-Start ------------------- C-End      |      |   
|    |       |                           |         |      |
V    V       V                           V         V      V      
1 thread->|<-A-|<--B---|<-C-|-A-|-C-|--A--|-B-|--C-->|---A---->|--B-->| 

因此,据我所知,单线程异步代码仍然是同步的,但它给每个任务一点时间,如果有很多事情要做,异步代码基本上会说,当工作完成时给我回电话,好吧,但如果我们只有一个线程来做这项工作,而你把资源交给另一个代码

为了向您展示问题,让我们看看我们项目中的示例:

public void getAllExercises(RequestListener<List<Exercise>> listener) {
getAllExercisesRequest().getAsObjectList(Exercise.class, listener);
}

该方法的用法:当用户点击一个按钮查看所有练习时,就会调用该方法,它所做的是从服务器获取所有练习,下面是一个用法示例:

class sometingAdapter extends something{
someMethod(param){
.
. 
.  
//some code before the Method call 
DBClient.getstandardDBClient().getAllExercises(new RequestListener<List<Exercise>>() {
@Override
public void onResponse(List<Exercise> response) {
arrayAdapter.addAll(response);
arrayAdapter.notifyDataSetChanged();
}
});

//some additional code 
return v;
}-> end of the method
}

声明是,现在当方法从服务器获取数据时,我们的UI没有被阻止,并且可以执行其他操作,但如何执行呢?当代码执行到达行CCD_ 1时,方法CCD_。在该方法中,建立了一个请求并调用getAsObject(MyClass.class, listener)方法(我不知道getAsObject()方法是如何工作的,它来自FAN API),

但在所有这些中,我们或系统告诉代码的地方,听着,你可以回去做你的事情,当我有数据(响应)时,我会用你作为参数传递的listener中的onResponse()方法回调

谁来获取数据我们只有一个线程,当我们的线程忙于执行其他代码时,没有神奇的资源来获取数据?当其他代码正在运行时,系统如何知道跳回何处?其不相似的系统类似于";哦,他是异步的,我会神奇地跳来跳去

因此,在这种神奇的情况发生后,还有一件事让我感到困惑,而当代码的进一步执行到达return v语句时,对getAllExercise的调用仍然是活动的,不是这样函数调用就从堆栈中删除了吗?这进一步意味着获取也会被中断等。基本上,这会引起连锁反应,onResponse()方法永远不会被调用,还是会被调用

是什么使代码异步,它是否只传递一个回调方法,即其方法用作回调的对象?如果是这样的话,那怎么不阻塞UI呢?如果我调用一个方法并将这个方法传递给另一个方法,那么代码的执行将在该方法内部,直到传递的方法被调用,然后代码的执行就会开始,所以UI仍然存在阻塞——没有神奇的跳跃和在后台工作,我缺少什么?

void Method1(Method2);
|Start 
|call Method1------------>|
|                         |                         
| Blocked??               |Execution of Method 1
|                         |
| <-----------------------|
|    callback Method2
| continued execution 
| 
|
|End 

那么,当被阻塞的部分变得不被阻塞时,魔法在哪里发生呢?方法1的执行和其余的同时发生?

我的理解是,不知何故发生了以下情况:

void Method1(Method2);
|Start 
|call Method1------------------>|
continues execution of main thread|<------------------------------|                         
|(okay thanks for the Method    |Execution of Method 1
|I will call you when I am done)|but what resource is executing 
| <---------------------------- |Method 1????
|    callback Method2: Iam done 
| ------------------------------>|execution of method 2 
|  Blocked                       |very quick not noticable 
|<-------------------------------
|continued execution
|End


通常在Java中,如果您不想阻止UI,则将不得不在另一个线程上运行复杂的任务。在不知情的情况下";风扇API";我几乎可以肯定地说,getAsObjectList(...)正在启动第二个线程。

这个方法返回时不会有明显的延迟,并允许当前线程继续,即防止UI阻塞。它不是同步启动请求,而是启动一个新线程(或者更确切地说,从线程池中获取一个线程),并使用它来发送和等待请求。当收到响应时,它将从这个线程(或者可能是另一个线程)调用您的RequestListener。也就是说,它将使用调用DBClient.getStandardDBClient().getAllExercises0的线程来运行RequestListener,因为该线程很久以前已经从getAsObjectList(...)返回,并且不能是"0";受控的";不再"特别是不会有一些";魔术;在继续执行的任何随机点自由地中断线程,并将CCD_。


:如果getAllExercises(...)是从某个线程调用的,该线程是基于线程池/某个事件队列的并发框架(可能是UI框架的一部分)的一部分,那么实际上可能的,这个线程将有意(甚至只是意外)被重用来调用RequestListener。例如,请参阅JavaScript的并发模型,其中所有(客户端)代码只在单个线程中运行,同时仍然允许/鼓励/强制异步性。然而,在您的客户端代码顺利执行getAsObjectList(...)调用之前,这种情况仍然不会发生。只有在执行完成之后,并且线程已返回到其池中的某个休息状态,等待更多的任务运行,它才能被选为现在调用RequestListener的线程。

最新更新