黑马程序员技术交流社区
标题:
同步和异步有何异同,在什么情况下分别使用它们?
[打印本页]
作者:
hmwudizl91zl
时间:
2013-10-5 23:15
标题:
同步和异步有何异同,在什么情况下分别使用它们?
本帖最后由 hmwudizl91zl 于 2013-10-6 11:13 编辑
求解,越详细越好,看的有点乱
作者:
FFF
时间:
2013-10-5 23:21
本帖最后由 FFF 于 2013-10-5 23:44 编辑
所谓同步就是一个任务的完成需要依赖另外一个任务时,只有等待被依赖的任务完成后,依赖的任务才能算完成,这是一种可靠的任务序列。要么成功都成功,失败都失败,两个任务的状态可以保持一致。而异步是不需要等待被依赖的任务完成,只是通知被依赖的任务要完成什么工作,依赖的任务也立即执行,只要自己完成了整个任务就算完成了。至于被依赖的任务最终是否真正完成,依赖它的任务无法确定,所以它是不可靠的任务序列。
网上有很多网友用很通俗的比喻 把同步和异步讲解的很透彻 转过来
举个例子:普通B/S模式(同步)AJAX技术(异步)
同步:提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事
异步: 请求通过事件触发->服务器处理(这是浏览器仍然可以作其他事情)->处理完毕
同步就是你叫我去吃饭,我听到了就和你去吃饭;如果没有听到,你就不停的叫,直到我告诉你听到了,才一起去吃饭。
异步就是你叫我,然后自己去吃饭,我得到消息后可能立即走,也可能等到下班才去吃饭。
再举个例子:
打电话,同步。我请你吃饭,打电话问你你来不来。你回答了说来就一起去吃饭,那我请你吃饭成功。你说不来那请你吃饭失败,我也不去了。一直等你答复。
发短信,异步。还是请你吃饭,发信息,问你来不来,然后我先吃饭,你来了,就请你吃(请吃饭成功),你没来我就自己吃(但是请你吃饭失败)。不等你答复。
作者:
蔚蓝天色
时间:
2013-10-5 23:38
什么是异步:当你extends Thread或implements Runnable时,调用start()启用了ABC个线程去吃饭,但是Cpu指定了他们只有一个人能吃,ABC其中一个在吃的时候谁也不知道能吃多久,Cpu就要叫其他人替代当前吃饭的线程去吃了,也就是说他们三个人当中的其中一个只吃了几口就被其他两条线程之一抢到了Cpu的控制权去吃饭了。
什么是同步:同步分了很多种,大概的意思就是无论你有多少线程在就绪状态等待被Cpu分配执行权,当前可执行的线程只有一个,并且,要等待执行结束
作者:
晓天s
时间:
2013-10-6 07:58
如果数据将在线程间共享.例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取.
当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率.
Java同步:
基本概念:
每个Object都会有1个锁.
同步就是串行使用一些资源.
(说明:以下有些例子为了突出重点,省略了不必要的代码.非凡是省掉了一些成员变量,就是需要同步的对象.)
1. 多线程中对共享、可变的数据进行同步.
对于函数中的局部变量没必要进行同步.
对于不可变数据,也没必要进行同步.
多线程中访问共享可变数据才有必要.
2. 单个线程中可以使用synchronized,而且可以嵌套,但无意义.
class Test {
public static void main(String[] args) {
Test t = new Test();
synchronized(t) {
synchronized(t) {
System.out.println("ok!");
}
}
}
}
3. 对象实例的锁
class Test{
public synchronized void f1(){
//do something here
}
public void f2(){
synchronized(this){
//do something here
}
}
}
上面的f1()和f2()效果一致, synchronized取得的锁都是Test某个实列(this)的锁.
比如: Test t = new Test();
线程A调用t.f2()时, 线程B无法进入t.f1(),直到t.f2()结束.
作用: 多线程中访问Test的同一个实例的同步方法时会进行同步.
4. class的锁
class Test{
final static Object o= new Object();
public static synchronized void f1(){
//do something here
}
public static void f2(){
synchronized(Test.class){
//do something here
}
}
public static void f3(){
try {
synchronized (Class.forName("Test")) {
//do something here
}
}
catch (ClassNotFoundException ex) {
}
}
public static void g(){
synchronized(o){
//do something here
}
}
}
上面f1(),f2(),f3(),g()效果一致
f1(),f2(),f3()中synchronized取得的锁都是Test.class的锁.
g()是自己产生一个对象o,利用o的锁做同步
作用: 多线程中访问此类或此类任一个实例的同步方法时都会同步. singleton模式lazily initializing属于此类.
5. static method
class Test{
private static int v = 0;
public static void f1(){
//do something, 但函数中没用用到v
}
public synchronized static void f2(){
//do something, 函数中对v进行了读/写.
}
}
多线程中使用Test的某个实列时,
(1) f1()是线程安全的,不需要同步
(2) f2()这个静态方法中使用了函数外静态变量,所以需要同步.
Java异步:
一. 它要能适应不同类型的请求:
本节用 makeString来说明要求有返回值的请求.用displayString来说明不需要返回值的请求.
二. 要能同时并发处理多个请求,并能按一定机制调度:
本节将用一个队列来存放请求,所以只能按FIFO机制调度,你可以改用LinkedList,就可以简单实现一个优先级(优先级高的addFirst,低的addLast).
三. 有能力将调用的边界从线程扩展到机器间(RMI)
四. 分离过度耦合,如分离调用句柄(取货凭证)和真实数据的实现.分离调用和执行的过程,可以尽快地将调返回.
现在看具体的实现:
public interface Axman {
Result resultTest(int count,char c);
void noResultTest(String str);
}
这个接口有两个方法要实现,就是有返回值的调用resultTest和不需要返回值的调用
作者:
麦子
时间:
2013-10-6 08:20
哥么,最直接的回答:
同步是防止一个数据被两人同时用,造成数据的破坏,异步是为了加快程序的运行。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2