是什么让异步单线程 java 代码异步
What makes asynchronous single threaded java code asynchronous
所以我们目前正在 java 开发一个应用程序,一位同事向我介绍了异步编程,不管我研究了多少,对我来说它似乎是同步的。
所以异步代码的主要优点似乎是 UI 的非冻结,而一些动作需要很长时间才能执行并让我们返回结果,我们需要做的就是给那个函数一个回调函数,它是工作完成后将被调用。据我从网上资源和Whosebug上的类似问题了解到,代码可以是单线程和异步的,甚至有人画成这样:
异步(一个线程)(信用:Asynchronous vs synchronous execution, what does it really mean?):
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 没有被阻止,可以执行其他操作,但是如何?当代码执行到行 DBClient.getStandardDBClient().getAllExercises
时,方法 getAllExercises
被调用,执行跳转到该方法。在该方法中,构建了一个请求并调用了 getAsObject(MyClass.class, listener)
方法(我不知道 getAsObject()
方法是如何工作的,它来自 FAN API),
但是我们或系统在哪里告诉代码,听着,你可以回去做你的事情,当我有数据(响应)时,我将使用您作为参数传递的 listener
中的 onResponse()
方法给您回电
谁负责获取数据我们只有一个线程,当我们的线程忙于执行其他代码时,没有神奇的资源来获取数据?
当另一个代码是 运行 时,系统如何知道要跳回哪里?它不像系统那样“哦,他正在做异步我会神奇地跳来跳去”
所以在这个魔法发生之后还有一件让我感到困惑的事情,当代码的进一步执行到达 return v
语句 [=51 时,对 getAllExercises 的调用仍然有效=] 是不是这样函数调用就从堆栈中移除,这进一步意味着 getAllExercise 方法的执行将被中断?这进一步意味着获取也将被中断等。基本上它会导致连锁反应并且永远不会调用 onResponse() 方法或者会吗?
什么使代码异步,它是否只传递一个回调方法,即其方法用作回调的对象?如果是这样,那怎么不阻塞UI,如果我调用一个方法并将该方法传递给另一个方法,那么代码的执行将在该方法内部,直到调用传递的方法,然后该代码的执行将开始,所以仍然存在 UI 的阻塞,没有神奇的跳跃和在后台工作,我错过了什么?
void Method1(Method2);
|Start
|call Method1------------>|
| |
| Blocked?? |Execution of Method 1
| |
| <-----------------------|
| callback Method2
| continued execution
|
|
|End
那么,阻塞部分变得畅通无阻的神奇之处在哪里呢?并且 method1 和其余方法的执行同时发生?
我的理解是不知何故发生了以下情况:
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 阻塞,您 将 必须 运行 复杂的任务另一个线程。在不知道这个“FAN API”的情况下,我几乎可以肯定地说,getAsObjectList(...)
正在启动第二个线程。
此方法将 return 没有明显的延迟,并允许当前线程继续,即。 e.防止 UI 阻塞。它不是启动请求 同步 ,而是启动一个新线程(或者更确切地说,从线程池中获取一个线程)并使用它来发送和等待请求。
当收到响应时,它将从该线程(或可能还有另一个)调用您的 RequestListener
。也就是说,它将不使用调用getAsObjectList(...)
的线程到运行RequestListener
,因为那个线程有return ] 很久以前从 getAsObjectList(...)
编辑并且不能再被“控制”。¹ 特别是不会有一些“魔法”在继续执行的任何随机点自由地中断线程并强行填充 [= 的执行11=]进入其控制流。
¹:如果 getAllExercises(...)
是从某个线程调用的,它是基于线程 pool/some 事件队列的并发框架的一部分(可能是 UI 框架的一部分),它在事实上 是 可能的,该线程将有意(或什至只是偶然地)被重用以调用 RequestListener
。参见,例如 JavaScript's concurrency model,其中所有(客户端)代码仅在单个线程中 运行,同时仍然 allowing/encouraging/enforcing 异步。但是,在 getAsObjectList(...)
调用周围的客户端代码顺利执行之前,这仍然不会发生。只有在该执行完成后,线程已 return 进入其池中的某个静止状态,等待更多任务进入 运行,它才能被选为现在调用 RequestListener
上。
所以我们目前正在 java 开发一个应用程序,一位同事向我介绍了异步编程,不管我研究了多少,对我来说它似乎是同步的。 所以异步代码的主要优点似乎是 UI 的非冻结,而一些动作需要很长时间才能执行并让我们返回结果,我们需要做的就是给那个函数一个回调函数,它是工作完成后将被调用。据我从网上资源和Whosebug上的类似问题了解到,代码可以是单线程和异步的,甚至有人画成这样:
异步(一个线程)(信用:Asynchronous vs synchronous execution, what does it really mean?):
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 没有被阻止,可以执行其他操作,但是如何?当代码执行到行 DBClient.getStandardDBClient().getAllExercises
时,方法 getAllExercises
被调用,执行跳转到该方法。在该方法中,构建了一个请求并调用了 getAsObject(MyClass.class, listener)
方法(我不知道 getAsObject()
方法是如何工作的,它来自 FAN API),
但是我们或系统在哪里告诉代码,听着,你可以回去做你的事情,当我有数据(响应)时,我将使用您作为参数传递的 listener
中的 onResponse()
方法给您回电
谁负责获取数据我们只有一个线程,当我们的线程忙于执行其他代码时,没有神奇的资源来获取数据? 当另一个代码是 运行 时,系统如何知道要跳回哪里?它不像系统那样“哦,他正在做异步我会神奇地跳来跳去”
所以在这个魔法发生之后还有一件让我感到困惑的事情,当代码的进一步执行到达 return v
语句 [=51 时,对 getAllExercises 的调用仍然有效=] 是不是这样函数调用就从堆栈中移除,这进一步意味着 getAllExercise 方法的执行将被中断?这进一步意味着获取也将被中断等。基本上它会导致连锁反应并且永远不会调用 onResponse() 方法或者会吗?
什么使代码异步,它是否只传递一个回调方法,即其方法用作回调的对象?如果是这样,那怎么不阻塞UI,如果我调用一个方法并将该方法传递给另一个方法,那么代码的执行将在该方法内部,直到调用传递的方法,然后该代码的执行将开始,所以仍然存在 UI 的阻塞,没有神奇的跳跃和在后台工作,我错过了什么?
void Method1(Method2);
|Start
|call Method1------------>|
| |
| Blocked?? |Execution of Method 1
| |
| <-----------------------|
| callback Method2
| continued execution
|
|
|End
那么,阻塞部分变得畅通无阻的神奇之处在哪里呢?并且 method1 和其余方法的执行同时发生?
我的理解是不知何故发生了以下情况:
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 阻塞,您 将 必须 运行 复杂的任务另一个线程。在不知道这个“FAN API”的情况下,我几乎可以肯定地说,getAsObjectList(...)
正在启动第二个线程。
此方法将 return 没有明显的延迟,并允许当前线程继续,即。 e.防止 UI 阻塞。它不是启动请求 同步 ,而是启动一个新线程(或者更确切地说,从线程池中获取一个线程)并使用它来发送和等待请求。
当收到响应时,它将从该线程(或可能还有另一个)调用您的 RequestListener
。也就是说,它将不使用调用getAsObjectList(...)
的线程到运行RequestListener
,因为那个线程有return ] 很久以前从 getAsObjectList(...)
编辑并且不能再被“控制”。¹ 特别是不会有一些“魔法”在继续执行的任何随机点自由地中断线程并强行填充 [= 的执行11=]进入其控制流。
¹:如果 getAllExercises(...)
是从某个线程调用的,它是基于线程 pool/some 事件队列的并发框架的一部分(可能是 UI 框架的一部分),它在事实上 是 可能的,该线程将有意(或什至只是偶然地)被重用以调用 RequestListener
。参见,例如 JavaScript's concurrency model,其中所有(客户端)代码仅在单个线程中 运行,同时仍然 allowing/encouraging/enforcing 异步。但是,在 getAsObjectList(...)
调用周围的客户端代码顺利执行之前,这仍然不会发生。只有在该执行完成后,线程已 return 进入其池中的某个静止状态,等待更多任务进入 运行,它才能被选为现在调用 RequestListener
上。