SynchronizationContext(同步上下文)综述
- 1. 概述
- 2. 同步上下文 的必要性
- 3. 同步上下文 的概念
- 4. 同步上下文 的实现
- 5. 同步上下实现类 的注意事项
- 6. AsyncOperationManager 和 AsyncOperation
- 7. 同步上下文 的Library支持示例
- 8. 限制和功能
1. 概述
注意: 本篇文章讲述的是在 .Net Framework 环境下的分析, 但是我相信这与 .Net Core 设计思想是一致,但在实现上一定优化了很多。
下面开始本次讲述:
无论是什么平台(ASP.NET 、WinForm 、WPF 等),所有 .NET 程序都包含 同步上下文 概念,并且所有多线程编程人员都可以通过理解和应用它获益。
2. 同步上下文 的必要性
2.1. ISynchronizeInvoke 的诞生
原始多线程
- 多线程程序在 .NET Framework 出现之前就存在了。
- 这些程序通常需要一个线程将一个工作单元传递给另一个线程。
- Windows 程序围绕消息循环进行,因此很多编程人员使用这一内置队列传递工作单元。
- 每个要以这种方式使用 Windows 消息队列的多线程程序都必须自定义 Windows 消息以及处理约定。
ISynchronizeInvoke 的诞生
- 当
.NET Framework首次发布时,这一通用模式是标准化模式。 - 那时 .NET 唯一支持的 GUI 应用程序类型是 WinFrom。
- 不过,框架设计人员期待其他模型,他们开发出了一种通用的解决方案,
ISynchronizeInvoke诞生了。
- 当
ISynchronizeInvoke 的原理
- 一个“源”线程可以将一个委托列入“目标”线程队列。
ISynchronizeInvoke还提供了一个属性来确定当前代码是否已在目标线程上运行。- WinForm 提供了单例的
ISynchronizeInvoke实现,并且开发了一种模式来设计异步组件。
2.2. SynchronizationContext 的诞生
- ASP.NET 异步页面
- .NET Framework 2.0 版包含很多重大改动。 其中一项重要改进是在 ASP.NET 体系结构中引入了异步页面。
- 在 .NET Framework 2.0 之前的版本中,每个 ASP.NET 请求都需要一个线程,线程会直到该请求完成。
- 这会造成线程利用率低下,因为创建网页通常依赖于数据库查询和 Web 服务调用,并且处理请求的线程必须等待,直到所有这些操作结束。
- 后来使用异步页面,处理请求的线程可以开始每个操作,然后返回到 ASP.NET 线程池;当操作结束时,ASP.NET 线程池的另一个线程可以完成该请求。
ISynchronizeInvoke不太适合 ASP.NET 异步页面体系结构。- 使用
ISynchronizeInvoke模式开发的异步组件在 ASP.NET 页面内无法正常工作,因为 ASP.NET 异步页面不与单个线程关联。 - 需要设计出,无须将工作排入原来的线程队列,异步页面只需对未完成的操作进行计数 以确定页面请求何时可以完成。
- 使用
- .NET Framework 2.0 版包含很多重大改动。 其中一项重要改进是在 ASP.NET 体系结构中引入了异步页面。
- 经过精心设计,
SynchronizationContext取代了ISynchronizeInvoke。
3. 同步上下文 的概念
ISynchronizeInvoke 满足了两点需求:
- 确定是否必须同步
- 使工作单元从一个线程列队等候另一个线程。
设计 SynchronizationContext 是为了替代 ISynchronizeInvoke ,但完成设计后,它就不仅仅是一个替代品了。
- 一方面,
SynchronizationContext提供了一种方式,可以使工作单元列队并列入上下文。- 请注意,工作单元是列入上下文,而不是某个特定线程。
- 这一区别非常重要,因为很多
SynchronizationContext实现都不是基于单个特定线程的。 SynchronizationContext不包含用来确定是否必须同步的机制,因为这是不可能的。- WPF 中的
Dispatcher.Invoke是将委托列入上下文,不等委托执行直接返回 - WinForm 中的
txtUName.Invoke会启动一个process,等到委托执行完毕后返回
- WPF 中的
- 另一方面,每个线程都有当前同步上下文。
- 线程上下文不一定唯一;
- 其上下文实例可以与多个其他线程共享。
- 线程可以更改其当前上下文,但这样的情况非常少见。
- 第三个方面,保持了未完成操作的计数。
- 这样,就可以用于 ASP.NET 异步页面和需要此类计数的任何其他主机。
- 大多数情况下,捕获到当前 SynchronizationContext 时,计数递增;
- 捕获到的 SynchronizationContext 用于将完成通知列队到上下文中时,计数递减
void OperationCompleted()。
- 捕获到的 SynchronizationContext 用于将完成通知列队到上下文中时,计数递减
- 其他一些方面,这些对大多数编程人员来说并不那么重要。
// SynchronizationContext API的重要方面
class SynchronizationContext
{
// 将工作分配到上下文中
void Post(..); // (asynchronously 异步)
void Send(..); // (synchronously 同步)
// 跟踪异步操作的数量。
void OperationStarted();
void OperationCompleted();
// 每个线程都有一个Current Context。
// 如果“Current”为null,则按照惯例,
// 最开始的当前上下文为 new SynchronizationContext()。
static SynchronizationContext Current { get; }
//设置当前同步上下文
static void SetSynchronizationContext(SynchronizationContext);
}
4. 同步上下文 的实现
不同的框架和主机可以自行定义上下文
通过了解这些不同的实现及其限制,可以清楚了解 SynchronizationContext 概念可以和不可以实现的功能
4.1. WinForm 同步上下文
位于:System.Windows.Forms.dll:System.Windows.Forms
WinForm
- WinForm应用程序会创建并安装一个
WindowsFormsSynchronizationContext- 作为创建
UI Control的每个线程的当前上下文 - 一个 WinForm 应用程序对应一个同步上下文
- 作为创建
- 这一
SynchronizationContext使用UI Control的Invoke等方法(ISynchronizeInvoke派生出来的),该方法将委托传递给基础Win32消息循环 WindowsFormsSynchronizationContext的上下文是一个单例的 UI 线程- 在
WindowsFormsSynchronizationContext列队的所有委托一次一个地执行- 这个已排序的委托队列,被一个特定 UI 线程执行完
4.2. Dispatcher 同步上下文
位于:WindowsBase.dll:System.Windows.Threading
WPF
- 委托按“Normal”优先级在 UI 线程的
Dispatcher中列队 - 当一个线程通过调用
Dispatcher.Run开启 循环调度器 时,将这个初始化完成的 同步上下文 安装到当前上下文 DispatcherSynchronizationContext的上下文是一个单独的 UI 线程。- 排队到
DispatcherSynchronizationContext的所有委托均由特定的UI线程一次一个按其排队的顺序执行 - 当前实现为每个顶层窗口创建一个
DispatcherSynchronizationContext,即使它们都使用相同的基础调度程序也是如此。
4.3. Default 同步上下文
调度线程池线程的同步上下文。
位于:mscorlib.dll:System.Threading
Default SynchronizationContext 是默认构造的 SynchronizationContext 对象。
- 根据惯例,如果一个线程的当前 SynchronizationContext 为 null,那么它隐式具有一个
Default SynchronizationContext。 Default SynchronizationContext将其异步委托列队到ThreadPool,但在调用线程上直接执行其同步委托。- 因此,
Default SynchronizationContext涵盖所有ThreadPool线程以及任何调用Send的线程。 - 这个上下文“借助”调用
Send的线程们,将这些线程放入这个上下文,直至委托执行完成- 从这种意义上讲,默认上下文可以包含进程中的所有线程。
Default SynchronizationContext应用于 线程池 线程,除非代码由 ASP.NET 承载。Default SynchronizationContext还隐式应用于显式子线程(Thread 类的实例),除非子线程设置自己的SynchronizationContext。
因此,UI 应用程序通常有两个同步上下文:
- 包含 UI 线程的
UI SynchronizationContext - 包含 ThreadPool 线程的
Default SynchronizationContext
4.4. 上下文捕获和执行
BackgroundWorker运行流程
- 首先
BackgroundWorker捕获并使用调用RunWorkerAsync的线程的 同步上下文 - 然后,在
Default SynchronizationContext中执行DoWork - 最后,在之前捕获的上下文中执行其
RunWorkerCompleted事件
UI同步上下文 中只有一个 BackgroundWorker ,因此 RunWorkerCompleted 在 RunWorkerAsync 捕获的 UI同步上下文中执行(如下图)。

UI同步上下文中的嵌套 BackgroundWorker
- 嵌套:
BackgroundWorker从其DoWork处理程序启动另一个BackgroundWorker- 嵌套的
BackgroundWorker不会捕获 UI同步上下文
- 嵌套的
DoWork由 线程池 线程使用 默认同步上下文 执行。- 在这种情况下,嵌套的
RunWorkerAsync将捕获默认SynchronizationContext - 因此它将由一个 线程池 线程而不是 UI线程 执行其
RunWorkerCompleted - 这样会导致异步执行完后,后面的代码就不在UI同步上下文中执行了(如下图)。
- 在这种情况下,嵌套的

默认情况下,控制台应用程序 和 Windows服务 中的所有线程都只有 Default SynchronizationContext,这会导致一些基于事件的异步组件失败(也就是没有UI同步上下文的特性)
- 要解决这个问题,可以创建一个显式子线程,然后将 UI同步上下文 安装在该线程上,这样就可以为这些组件提供上下文。
Nito.Async库的ActionThread类可用作通用同步上下文实现。
4.5. AspNetSynchronizationContext
位于:System.Web.dll:System.Web [internal class]
ASP.NET
SynchronizationContext在线程池线程执行页面代码时安装完成。- 当一个委托列入到捕获的
AspNetSynchronizationContext中时,它设置原始页面的 identity 和 culture 到此线程,然后直接执行委托- 即使委托是通过调用
Post“异步”列入的,也会直接调用委托。
- 即使委托是通过调用
从概念上讲, AspNetSynchronizationContext 的上下文非常复杂。
- 在异步页面的生命周期中,该同步上下文从来自 ASP.NET 线程池的一个线程开始。
- 异步请求开始后,该上下文不包含任何线程。
- 异步请求结束时,线程池线程进入该上下文并执行 处理完成的相关工作
- 这可能是启动请求的线程,但更可能是操作完成时处于空闲状态的任何线程。
- 如果同一应用程序的多项操作同时完成,
AspNetSynchronizationContext确保一次只执行其中一项。它们可以在任意线程上执行,但该线程将具有原始页面的 identity 和 culture。
一个常见的示例:
在异步网页中使用 WebClient.DownloadDataAsync 将捕获当前 SynchronizationContext ,之后在该上下文中执行其 DownloadDataCompleted 事件。
- 当页面开始执行时,ASP.NET 会分配一个线程执行该页面中的代码。
- 该页面可能调用
DownloadDataAsync,然后返回;- ASP.NET 对未完成的异步操作进行计数,以便了解页面处理是否已完成。
- 当
WebClient对象下载所请求的数据后,它将在线程池线程上收到通知- 该线程将在捕获的上下文中引发
DownloadDataCompleted
- 该线程将在捕获的上下文中引发
- 该上下文将保持在相同的线程中,但会确保事件处理的运行使用正确的 identity 和 culture 运行
5. 同步上下实现类 的注意事项
SynchronizationContext提供了一种途径,可以在很多不同框架中编写组件BackgroundWorker和WebClient就是两个在WinForm、WPF、Console和ASP.NET Application中同样应用自如的组件。
在设计这类可重用组件时,必须注意几点:
同步上下文的实现们不是平等可比的。
- 这意味着没有类似
ISynchronizeInvoke.InvokeRequired的等效项- 此属性确定在对如
Concrol对象进行方法调用时,调用方是否必须通过Invoke进行调用(传入委托)。 - 这样的(
Control)对象被绑定到特定线程,并且不是线程安全的。 - 如果要从其他线程调用对象的方法,则必须借助
Invoke方法将对相应线程调用的委托列队
- 此属性确定在对如
- 不过,这不是多大的缺点;代码更为清晰,并且更容易验证它是否始终在已知上下文中执行,而不是试图处理多个上下文。
- 这意味着没有类似
不是所有 同步上下文的实现 都可以保证委托执行顺序或委托同步顺序。
- UI同步上下文 满足上述条件
- ASP.NET同步上下文 只提供同步
- Default同步上下文 不保证执行顺序或同步顺序
同步上下文实例和线程之间没有 1:1 的对应关系
WindowsFormsSynchronizationContext确实 1:1 映射到一个线程(只要不调用SynchronizationContext.CreateCopy)- 任何其他实现都不是这样
- 一般而言,最好不要假设任何上下文实例将在任何指定线程上运行
SynchronizationContext.Post方法不一定是异步的- 大多数实现异步实现此方法,但
AspNetSynchronizationContext是一个明显的例外 - 这可能会导致无法预料的重入问题
- 大多数实现异步实现此方法,但
同步上下文实现类的摘要
| 使用特定线程 执行委托 | 独占 (一次执行一个委托) | 有序 (委托按队列顺序执行) | Send 可以直接调用委托 | Post 可以直接调用委托 | |
|---|---|---|---|---|---|
| Winform | 能 | 能 | 能 | 如果从UI线程调用 | 从不 |
| WPF/Silverlight | 能 | 能 | 能 | 如果从UI线程调用 | 从不 |
| Default | 不能 | 不能 | 不能 | Always | 从不 |
| ASP.NET | 不能 | 能 | 不能 | Always | Always |
6. AsyncOperationManager 和 AsyncOperation
AsyncOperationManager和AsyncOperation类是SynchronizationContext抽象类的轻型包装AsyncOperation的异步是使用抽象的同步上下文进行封装的
AsyncOperationManager在第一次创建AsyncOperation时捕获当前同步上下文 ,如果当前同步上下文为null,则使用Default同步上下文AsyncOperation将委托异步发布到捕获的 同步上下文- 大多数基于事件的异步组件都在其实现中使用
AsyncOperationManager和AsyncOperation- 这些对于具有明确完成点的异步操作非常有效
- 即异步操作从一个点开始,以另一个点的事件结束
- 其他异步通知可能没有明确的完成点;它们可能是一种订阅类型,在一个点开始,然后无限期持续
- 对于这些类型的操作,当触发了被订阅的事件,在事件处理中直接捕获和使用同步上下文
- 这些对于具有明确完成点的异步操作非常有效
新组件不应使用基于事件的异步模式
- 使用基于Task的异步模式
- 组件返回 Task 和 Task 对象,而不是通过 同步上下文 引发事件
- 基于
Task的 API 是 .NET 中异步编程的发展方向
7. 同步上下文 的Library支持示例
- 像
BackgroundWorker和WebClient这样的简单组件是隐式自带的- 隐藏了对同步上下文的捕获和使用。
- 很多 Libraries 以更可见的方式使用 同步上下文
- 通过使用
SynchronizationContext公开 API,Libraries 不仅获得了框架独立性,而且为高级最终用户提供了一个可扩展点。
- 通过使用
ExecutionContext- 是与执行的逻辑线程相关的所有信息提供单个容器。 这包括安全上下文、调用上下文和同步上下文
- 任何捕获线程的 ExecutionContext 的系统都会捕获当前 同步上下文
- 当恢复 ExecutionContext 时,通常也会恢复 同步上下文
7.1. WCF
WCF 有两个用于配置服务器和客户端行为的特性:
ServiceBehaviorAttribute和CallbackBehaviorAttribute- 这两个特性都有一个 Boolean 属性:UseSynchronizationContext
- 此特性的默认值为 true,这表示在创建通信通道时捕获当前 同步上下文 ,这一捕获的 同步上下文 用于使约定方法列队。
- 服务器使用 Default 同步上下文
- 客户端回调使用相应的 UI 同步上下文
- 在需要重入时,这会导致问题,如客户端调用的服务器方法回调客户端方法。在这类情况下,将
UseSynchronizationContext设置为false可以禁止 WCF 自动使用 同步上下文- 因为如果这时如果客户端使用的是UI同步上下文,可能造成不可预期的问题
7.2. Workflow Foundation (WF)
WorkflowInstance类及其派生的WorkflowApplication类的SynchronizationContext属性如果承载进程创建自己拥有的
WorkflowInstance,同步上下文也许直接设置了WorkflowInvoker.InvokeAsync也使用 同步上下文- 它捕获当前 同步上下文 并将其传递给其
internal的WorkflowApplication- 该 同步上下文 用于
Post工作流完成事件以及工作流活动
- 该 同步上下文 用于
- 它捕获当前 同步上下文 并将其传递给其
7.3. Task Parallel Library (TPL)
TaskScheduler.FromCurrentSynchronizationContext
TPL 使用 Task 对象作为其工作单元并通过 TaskScheduler 执行。
- 默认
TaskScheduler的作用类似于 Defalut 同步上下文 ,将Task在ThreadPool中列队。 - TPL 队列还提供了另一个
TaskScheduler,将Task在 一个同步上下文 中列队- UI 进度条更新 可以在一个嵌套
Task中完成,如下所示。
- UI 进度条更新 可以在一个嵌套
UI 进度条更新
private void button1_Click(object sender, EventArgs e)
{
// 捕获当前 SynchronizationContext 的 TaskScheduler.
TaskScheduler taskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
// Start a new task (this uses the default TaskScheduler,
// so it will run on a ThreadPool thread).
Task.Factory.StartNew(() =>
{
// We are running on a ThreadPool thread here.
// Do some work.
// Report progress to the UI.
Task reportProgressTask = Task.Factory.StartNew(() =>
{
// We are running on the UI thread here.
// Update the UI with our progress.
},CancellationToken.None,
TaskCreationOptions.None,
taskScheduler);
reportProgressTask.Wait();
// Do more work.
});
}
CancellationToken.Register
CancellationToken类可用于任意类型的取消操作- 为了与现有取消操作形式集成,该类允许注册委托以在请求取消时调用
- 当取消委托被注册后,同步上下文就可以传递了
- 当发起取消请求时,
CancellationToken将该委托列入 同步上下文 队列,然后才会进行执行
- 当发起取消请求时,
- 当取消委托被注册后,同步上下文就可以传递了
7.4. Reactive Extensions (Rx)
ObserveOn 、 SubscribeOn 和 SynchronizationContextScheduler
Rx 是一个库,它将事件视为数据流
ObserveOn(context)运算符通过一个 同步上下文 将事件列队SubscribeOn(context)运算符通过一个 同步上下文 将对这些事件的订阅 列队ObserveOn(context)通常用于使用传入事件更新 UI,SubscribeOn 用于从 UI 对象使用事件
Rx 还有它自己的工作单元列队方法: IScheduler 接口。
- Rx 包含
SynchronizationContextScheduler- 是一个将 Task 列入指定 同步上下文 的 IScheduler 实现。
- 构造方法:
SynchronizationContextScheduler(SynchronizationContext context)
7.5. 异步编程 Async
await 、 ConfigureAwait 、 SwitchTo 和 Progress<T>
- 默认情况下, 当前同步上下文 在一个
await关键字处被捕获 - 此 同步上下文 用于在运行到
await关键字后时恢复- 也就是
await关键字后面的执行代码会被列入到 该同步上下文 中执行- 仅当它不为
null时,才捕获当前 同步上下文 - 如果为
null,则捕获当前TaskScheduler
- 仅当它不为
- 也就是
private async void button1_Click(object sender, EventArgs e)
{
// 当前 SynchronizationContext 被 await 在暗中捕获
var data = await webClient.DownloadStringTaskAsync(uri);
// 此时,已捕获的SynchronizationContext用于恢复执行,
// 因此我们可以自由更新UI对象。
}
ConfigureAwait提供了一种途径避免SynchronizationContext捕获;- 为
continueOnCapturedContext参数传递false会阻止await后的代码,在await执行前的 同步上下文 上执行
- 为
同步上下文实例还有一种扩展方法
SwitchTo- 使用该方法,任何
async的方法 可以通过调用SwitchTo改变到一个不同的同步上下文上,并 awaiting 结果
- 使用该方法,任何
报告异步操作进展的通用模式:
IProgress<T>接口及其实现Progress<T>- 该类在构造时捕获 当前同步上下文
- 并在中引发其
ProgressChanged事件 - 所以实例化时,需要在 UI同步上下文 上执行
返回 void 的 async 方法
- 在异步操作开始时递增计数
- 在异步操作结束后递减计数
这一行为使返回 void 的 async 方法 类似于顶级异步操作。
8. 限制和功能
- 了解 同步上下文 对任何编程人员来说都是有益的
- 现有跨框架组件使用它同步其事件
- Libraries 可以将它公开以获得更高的灵活性
- 技术精湛的编程人员了解 同步上下文 限制和功能后,可以更好地编写和利用这些类
SynchronizationContext(同步上下文)综述的更多相关文章
- 【C# TAP 异步编程】四、SynchronizationContext 同步上下文|ExecutionContext
一.同步上下文(SynchronizationContext)概述 由来 多线程程序在.net框架出现之前就已经存在了.这些程序通常需要一个线程将一个工作单元传递给另一个线程.Windows程序以消息 ...
- c#同步上下文SynchronizationContext学习笔记
提供在各种同步模型中传播同步上下文的基本功能.同步上下文的工作就是确保调用在正确的线程上执行. 同步上下文的基本操作 Current 获取当前同步上下文 var context = Synchroni ...
- 执行上下文与同步上下文 | ExecutionContext 和 SynchronizationContext
原文连接:执行上下文与同步上下文 - .NET 并行编程 (microsoft.com) 执行上下文与同步上下文 斯蒂芬 6月15日, 2012 最近,我被问了几次关于 ExecutionContex ...
- 从执行上下文角度重新理解.NET(Core)的多线程编程[2]:同步上下文
一般情况下,我们可以将某项操作分发给任意线程来执行,但有的操作确实对于执行的线程是有要求的,最为典型的场景就是:GUI针对UI元素的操作必须在UI主线程中执行.将指定的操作分发给指定线程进行执行的需求 ...
- 【C# Task】理解Task中的ConfigureAwait配置同步上下文
原文:https://devblogs.microsoft.com/dotnet/configureawait-faq/ 作者:Stephen 翻译:xiaoxiaotank 静下心来,你一定会有收获 ...
- C#学习笔记之线程 - 同步上下文
同步上下文(Synchronization Contexts) 手动使用锁的一个替代方案是去声明锁.通过派生ContextBoundObject和应用Synchronization属性,你告诉CLR自 ...
- async异步操作和同步上下文
第8章 哪个线程运行我的代码 看到社区里的朋友没有翻译完这本书,我接着对一下的章节进行翻译 像我之前说的,异步编程就是关于线程的.那就意味着我们需要理解在C#程序中哪个.NET线程什么时候运行我们的代 ...
- 使用同步上下文进行C#与VBA代码和Excel之间的交互
原始出处:www.cnblogs.com/Charltsing/p/RunVBA.html 大家都知道,Excel是个STA,不允许在Excel忙的时候对其Com对象进行操作,也不允许同时有多个线程对 ...
- 利用SynchronizationContext.Current在线程间同步上下文
简而言之就是允许一个线程和另外一个线程进行通讯,SynchronizationContext在通讯中充当传输者的角色.另外这里有个地方需要清楚的,不是每个线程都附加SynchronizationCon ...
随机推荐
- Rainbow Plan团队项目第一次作业——项目计划
团队项目--Rainbow Plan英语学习App 1.团队简介 1.1团队名称:Rainbow Plan (彩虹计划) 1.2团队成员: 队员学号 队员姓名 201731024235 何继武(组长) ...
- 面试官问你MyBatis SQL是如何执行的?把这篇文章甩给他
初识 MyBatis MyBatis 是第一个支持自定义 SQL.存储过程和高级映射的类持久框架.MyBatis 消除了大部分 JDBC 的样板代码.手动设置参数以及检索结果.MyBatis 能够支持 ...
- robotframework,移动端(小程序)自动化,通过屏幕坐标点击对应按钮的方法
使用场景: 下图通过常规方法是定位不到“红色”这个按钮的 我们把鼠标放置上去,下图右侧会显示该点的坐标地址 然后使用click a point指令定位 click a point 64 743 dur ...
- chrome 安装
Centos7 yum安装chrome浏览器 跟着这个教程安装的:Centos7安装chrome浏览器 (点击) 1. 配置yum源 在目录 /etc/yum.repos.d/ 下新建文件 goo ...
- Nginx核心模块
error_log 语法:error_log file [ debug | info | notice | warn | error | crit ]默认值:${prefix}/logs/error. ...
- ios--->ios消息机制(NSNotification 和 NSNotificationCenter)
问题的背景 IOS中委托模式和消息机制基本上开发中用到的比较多,一般最开始页面传值通过委托实现的比较多,类之间的传值用到的比较多,不过委托相对来说只能是一对一,比如说页面A跳转到页面B,页面的B的值改 ...
- java架构之路-(netty专题)初步认识BIO、NIO、AIO
本次我们主要来说一下我们的IO阻塞模型,只是不多,但是一定要理解,对于后面理解netty很重要的 IO模型精讲 IO模型就是说用什么样的通道进行数据的发送和接收,Java共支持3种网络编程IO模式: ...
- MySQL学习笔记——基础与进阶篇
目录 一.###MySQL登录和退出 二.###MySQL常用命令 三.###MySQL语法规范 四.###基础查询 五.###条件查询 六.###排序查询 七.###常见函数的学习 八.###分组查 ...
- java8种基本数据类型
- Yandex Big Data Essentials Week1 Unix Command Line Interface File System exploration
File System Function In computing, a file system or filesystem is used to control how data is stored ...