A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 郝福明 中级黑马   /  2013-1-1 00:02  /  1968 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 郝福明 于 2013-1-1 22:10 编辑

同步和异步有什么不同?都是在什么情况下使用啊?

4 个回复

倒序浏览
本帖最后由 希望的曙光 于 2013-1-1 05:37 编辑

同步和异步最大的区别就在于。一个需要等待,一个不需要等待。
比如UDP:发送数据不关心接受者的状态,不需要的等待接受这回复
TCP:发送数据需要等待接收者,接通后,才能发送数据。
java中实现多线程

1)继承Thread,重写里面的run方法

2)实现runnable接口



举个例子:普通B/S模式(同步)AJAX技术(异步)

同步:提交请求->等待服务器处理->处理完返回这个期间客户端浏览器不能干任何事

异步:请求通过事件触发->服务器处理(这是浏览器仍然可以作其他事情)->处理完毕

可见,彼“同步”非此“同步”——我们说的java中的那个共享数据同步(synchronized)

一个同步的对象是指行为(动作),一个是同步的对象是指物质(共享数据)。



4、 Java同步机制有4种实现方式:(部分引用网上资源)

① ThreadLocal ② synchronized( ) ③ wait() 与 notify() ④ volatile

目的:都是为了解决多线程中的对同一变量的访问冲突

ThreadLocal
ThreadLocal 保证不同线程拥有不同实例,相同线程一定拥有相同的实例,即为每一个使用该

变量的线程提供一个该变量值的副本,每一个线程都可以独立改变自己的副本,而不是与其它线程

的副本冲突。

优势:提供了线程安全的共享对象

与其它同步机制的区别:同步机制是为了同步多个线程对相同资源的并发访问,是为了多个线程之

间进行通信;而 ThreadLocal 是隔离多个线程的数据共享,从根本上就不在多个线程之间共享资源

,这样当然不需要多个线程进行同步了。



 为了说明多线程访问对于类变量和ThreadLocal变量的影响,QuerySvc中分别设置了类变量sql和ThreadLocal变量,使用时先创建 QuerySvc的一个实例对象,然后产生多个线程,分别设置不同的sql实例对象,然后再调用execute方法,读取sql的值,看是否是set方法中写入的值。这种场景类似web应用中多个请求线程携带不同查询条件对一个servlet实例的访问,然后servlet调用业务对象,并传入不同查询条件,最后要保证每个请求得到的结果是对应的查询条件的结果。 在Java的多线程编程中,为保证多个线程对共享变量的安全访问,通常会使用synchronized来保证同一时刻只有一个线程对共享变量进行操作。但在有些情况下,synchronized不能保证多线程对共享变量的正确读写。例如类有一个类变量,该类变量会被多个类方法读写,当多线程操作该类的实例对象时,如果线程对类变量有读取、写入操作就会发生类变量读写错误,即便是在类方法前加上synchronized也无效,因为同一个线程在两次调用方法之间时锁是被释放的,这时其它线程可以访问对象的类方法,读取或修改类变量。这种情况下可以将类变量放到ThreadLocal类型的对象中,使变量在每个线程中都有独立拷贝,不会出现一个线程读取变量时而被另一个线程修改的现象。  下面举例说明: 

public class QuerySvc {  

private String sql;  

private static ThreadLocal sqlHolder = new ThreadLocal();  

public QuerySvc() {  }  public void execute() { 

 System.out.println("Thread " + Thread.currentThread().getId() +" Sql is " + sql); 

 System.out.println("Thread " + Thread.currentThread().getId() +" Thread Local variable Sql is " + sqlHolder.get());  }  
public String getSql() {  

        return sql;  }  

public void setSql(String sql) { 

          this.sql = sql;  sqlHolder.set(sql);  }

  }

  

使用QuerySvc的工作线程如下:

public class Work extends Thread {   .

private QuerySvc querySvc;   .

private String sql;   .

public Work(QuerySvc querySvc,String sql) {   .

this.querySvc = querySvc;  this.sql = sql;  }   .

public void run() {  querySvc.setSql(sql);  querySvc.execute();  }  }  .

 运行线程代码如下:  .

 QuerySvc qs = new QuerySvc();   .

for (int k=0; k<10; k++)   .

String sql = "--------------------------------;  .

 new Work(qs,sql).start(); .

  }


评分

参与人数 1技术分 +1 收起 理由
邵天强 + 1

查看全部评分

回复 使用道具 举报
额,楼上两个写得太多了,我就不说多了,其实同步问题归根结底就是共享数据的问题,也就是你要用一个东西,我也要使用这个东西,大家都要使用这个东西,这就存在一个同步问题了,到底谁先用呢?如果用的过程中出现了问题,到底怎么处理呢?这就是同步问题的现实体现。
相反,异步就不用解释了,大家各用各的东西(程序中表现就是数据),互不干扰。
回复 使用道具 举报
好多啊,结贴慢慢看
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马