`

同步、异步转化和任务执行

阅读更多

正如动静是相对的概念,有了它们,世界才充满盎然生气;变和不变也是哲学上的对立统一,在代码的世界里也一样;同步异步呢?在这一篇文字里面已经很粗略地提到了同步和异步各自有些什么好处,接下来,我不妨说一些同步和异步互相转化的故事。

 

先来看看这一段代码:

 

setTimeout(function(){
	while(true){
		alert("In");
	}
},0);
while(true){
	alert("Out");
}

 

它的输出应该是怎样的呢?你可以试一试。

不同浏览器下它的表现不同,有的浏览器下一直显示In的弹出框;有的浏览器下一直显示Out的弹出框;还有的浏览器下先显示一个Out,再不断显示In的弹出框。

那是不是可以这样理解:

上面的代码本意是想描述一个页面的JavaScript代码进行类似于并行线程的执行(setTimeout调用的方法,似乎就是一个异步执行的方法,它本意是不阻止主流程的执行的),可是实际运行的结果发现,原来浏览器运行JavaScript,所谓的异步,只是对开发人员和用户的一个欺骗,世界只是看起来这个样子——实际上,在JavaScript的世界里,其实根本就是“单线程”的嘛!

其实,这是无所谓欺骗的,就如同对于单CPU的机器来说,所谓的多进程,其实也只有一个CPU轮流执行队列里的指令。只是这个世界本来就是那么残酷,也许是我们都看错了……

 

 

同步Ajax和异步Ajax

Ajax通常都是异步的,同步的Ajax调用会将浏览器当前页面挂起,拒绝一切用户操作,直至响应到达:

 

var req = new  XMLHttpRequest();
req.open("GET", url, true);  //true表示异步,false表示同步
req.onreadystatechange  =  callback;
req.send();

 

 

JavaScript的一个悲剧

在JavaScript中,没有一个方法可以让主线程休息一段时间(Java中有sleep和wait),也就是说,如果我想在某一个执行逻辑中,休息一会、等待一会,这样的实现都会变得很困难(Jscex就是用来解决这样的问题的)。这似乎是JavaScript的一个天生的重大缺陷。

Jscex带来的最大好处,就在于可以用同步的思维和编码,来解决异步的问题:

 

var moveAsync = eval(Jscex.compile("$async", function(e, startPos, endPos, duration) {
    for (var t = 0; t < duration; t += 50) {
        e.style.left = startPos.x + (endPos.x - startPos.x) * (t / duration);
        e.style.top = startPos.y + (endPos.y - startPos.y) * (t / duration);
        $await(Jscex.Async.sleep(50));
    }
    e.style.left = endPos.x;
    e.style.top = endPos.y;
}));

 

 

Barrier模式

Barrier是一道篱笆,所有的不同异步线程,都先先后后运行完毕以后(都撞到了篱笆上),再汇成一束主流程继续往后走:


JDK的CyclicBarrier类就是用来实现这个模式的(A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point.):

 

class Solver {
	final int N;
	final float[][] data;
	final CyclicBarrier barrier;

	class Worker implements Runnable {
		int myRow;

		Worker(int row) {
			myRow = row;
		}

		public void run() {
			while (!done()) {
				processRow(myRow); //执行某一行的逻辑

				try {
					barrier.await(); //该行逻辑执行完毕后,告知一下
				} catch (InterruptedException ex) {
					return;
				} catch (BrokenBarrierException ex) {
					return;
				}
			}
		}
	}

	public Solver(float[][] matrix) {
     data = matrix;
     N = matrix.length;
     barrier = new CyclicBarrier(N,
                                 new Runnable() {
                                   public void run() {
                                     mergeRows(...); //在每一行都处理完毕以后,执行一个merge操作
                                   }
                                 });
     for (int i = 0; i < N; ++i)
       new Thread(new Worker(i)).start();

     waitUntilDone();
   }
}

 

而在JavaScript中,也可以实现类似的效果:

var count = 3;
for(var i=0; i<=count; i++){
	setTimeout(function(){
		doXXX(); // 执行任务
		count --; //每个子任务执行完毕后都标记一下
		if(!count)
			doFinalXXX(); //Barrier的汇总任务
	},0);
}

 

如果有了Jscex,实现可以更简洁:

function (taskA, taskB, taskC) {
    $await(Jscex.Async.parallel(taskA, taskB)); //先并行执行任务A、B
    $await(taskC); //在A、B都完成后再执行C
}

 

 

Future和Promise

Future、Promise是用于并发编程的一种同步构造。它们表示一个对象,这个对象用来作为一次计算的结果的代理,而该结果被初始化为未知,因为这个对象产生时计算还没有结束(或还没有开始)。

Java中有Future可以帮助实现:

 

ExecutorService executor = Executors.newSingleThreadExecutor();
Callable<Object> task = new Callable<Object>() {
	public Object call() throws Exception {
		doXXX();
		return result;
	}
};
Future<Object> future = executor.submit(task);
boolean isCancelled = future.isCancelled(); //查询状态,调用cancel方法可以取消任务
boolean isDone = future.isDone(); //查询状态
Object res = future.get(); // 等待至完成

 

JavaScript可以实现成类似这样子:

 

 

Promise.when(promise1, promise2).then(function (data1, data2) {...});

 

具体请参见这里

 

文章系本人原创,转载请注明出处和作者

  • 大小: 45 KB
0
0
分享到:
评论

相关推荐

    同步执行和异步执行学习Demo

    同步执行和异步执行是理解并发编程和多线程编程的关键概念。 **同步执行** 是一种线性、顺序的执行模式。在同步执行中,程序会按照代码的顺序逐行执行,如果某一步骤需要等待,例如读取文件、网络请求或计算密集型...

    基于Java的轻量级同步异步统一处理框架,基于协程思想构建.zip

    "基于Java的轻量级同步异步统一处理框架,基于协程思想构建"的项目旨在利用协程的优势,为Java开发者提供一个能够方便地处理同步和异步任务的框架。 协程是一种轻量级的执行单元,它允许多个任务在同一个线程中协同...

    [重要]基于Websphere MQ持久化消息实现异步转同步—方案二

    异步通信通常意味着发送方发送请求后,不需要立即等待响应,而是继续执行其他任务,接收方在处理完请求后会通过消息通知发送方。然而,在某些场景下,例如事务一致性要求高的操作,需要将异步通信转换为同步,确保...

    tornado-asyntool:一个简单的工具让 tornadoweb 异步运行代码

    5. **日志和监控**:Asyntool 可以与 Tornado 的日志系统无缝集成,提供任务执行的详细日志,便于监控和分析系统性能。 在实际项目中,Tornado Asyntool 可以广泛应用于实时数据处理、高并发Web服务、长连接管理等...

    Android使用OkHttp进行网络同步异步操作

    本文将详细讲解如何使用OkHttp进行网络同步和异步操作。 首先,理解同步和异步的概念至关重要。同步操作意味着在发送请求后,程序会阻塞等待直到收到响应,这通常会导致UI线程被阻塞,可能导致用户界面无响应。而...

    c++ 异步串口源码

    在实际开发中,异步串口通信的优势在于非阻塞特性,它允许程序在等待数据的同时执行其他任务,提高了程序的并发性和响应性。而同步串口通信则更简单直接,适合对实时性要求不高但需要保证数据完整性的场景。 总之,...

    阿里异步导入导出框架源码

    2. **事件驱动编程**:通过监听和触发事件,实现任务的异步执行。例如,当数据导入完成后,触发一个事件通知其他模块进行后续处理。 3. **线程池管理**:为了合理利用系统资源,框架可能采用了线程池来管理异步任务...

    AsyncControl异步控制渲染的特性

    AsyncControl的异步渲染特性意味着它可以将这个过程分解为多个独立的任务,这些任务可以并行执行,显著减少页面加载时间。例如,可以同时从多个API获取数据,然后合并结果来生成页面。 4. **性能提升** 使用...

    这个示例用于追踪用户位置,实现 继承异步类

    异步编程是处理长时间运行任务的关键,它允许程序在等待某一操作完成时继续执行其他任务,避免阻塞主线程,从而提高应用程序的响应性和用户体验。 首先,我们要理解异步编程的基本概念。在传统的同步编程中,代码按...

    用java的nio技术实现的异步连接池

    异步连接池的核心思想是将传统的同步操作转化为异步操作,这样在等待连接时,线程可以去做其他事情,而不是被阻塞。在Java中,可以使用NIO的Selector和Channel类来实现这一目标。Selector是NIO的关键组件,它可以...

    互联网背景下有哪些数据同步需求和解决方案看完我知道了.docx

    这是作者个人研发的延迟消息队列框架,提供了精准的定时任务和延迟队列处理,适用于需要精确控制任务执行时间的场景。通过mykit-delay,开发者可以更有效地管理和调度定时任务,避免全表扫描,提高数据同步效率。 ...

    基于FPGA的异步流水乘法器设计的教学方案.pdf

    此外,教师还可以安排相应的课程设计或实验项目,让学生在完成具体任务的过程中,进一步加深对异步电路设计方法的理解和掌握。通过这样的教学方案,学生将能够在理解异步电路设计的基本概念和方法的基础上,进一步...

    Java通过jQuery实现ajax异步请求

    4. **异步与同步**:AJAX的核心特性是异步,意味着请求不会阻塞页面的其他操作。通过设置`async: true`(默认值),可以确保请求在后台执行。如果需要等待请求完成再进行后续操作,可以使用`async: false`,但这会...

    Python实现基于协程的异步爬虫-内含源码以及设计说明书(可以自己运行复现).zip

    协程是Python中解决异步问题的一种高效方式,它允许在一个线程内暂停和恢复执行,而不会阻塞其他任务。`asyncio`库中的`asyncio.coroutine`装饰器可以将普通函数转化为协程,`await`关键字用于在执行过程中等待另一...

    PHP环境下的任务看板

    ajax.php是处理异步请求的关键,它接收来自前端的AJAX请求,执行相应的操作,如更新任务状态、添加新任务等,并返回处理结果。通过AJAX,可以实现实时更新,无需刷新整个页面,提高用户体验。 安装文件(install....

    异步控制方式的硬布线控制器(vhdl)

    4. **同步和异步信号处理**:在异步设计中,需要特别注意信号的同步问题,避免竞争冒险和亚稳态的发生。这可能需要引入边沿检测、同步化逻辑或者采用三态门等手段。 5. **进程设计**:使用VHDL的进程语句来描述状态...

    基于嵌入式LINUX的异步事件驱动数据采集模型.pdf

    在该模型中,数据采集任务被转化为一系列异步事件,每个事件都有自己的事件句柄。当数据源触发事件时,操作系统会自动进行事件分离和调度,然后调用相应的回调函数来处理数据。这种异步处理方式降低了对CPU的占用,...

    局域网聊天程序(xml保存)(异步套接字技术).rar

    异步套接字允许程序在等待网络I/O操作完成的同时,继续执行其他任务,提高了程序的响应速度和资源利用率。在C#.NET中,可以使用Socket类的BeginSend和BeginReceive等异步方法,配合回调函数来实现异步通信。这种方式...

    基于TTA的异步微处理器设计及其VLSI实现.pdf

    1. 异步微处理器:与传统的同步微处理器不同,异步微处理器不依赖于全局时钟信号来同步所有部件的操作。这种设计允许每个部件根据其自身的逻辑状态和数据可用性自主运行,从而可以提高能效、降低延迟并减少功耗。...

Global site tag (gtag.js) - Google Analytics