同步和异步最大的区别就在于。一个需要等待,一个不需要等待。 比如广播,就是一个异步例子。发起者不关心接收者的状态。不需要等待接收者的返回信息 电话,就是一个同步例子。发起者需要等待接收者,接通电话后,通信才开始。需要等待接收者的返回信息
多线程并发时,多个线程同时请求同一个资源,必然导致此资源的数据不安全,A线程修改了B线
程的处理的数据,而B线程又修改了A线程处理的数理。显然这是由于全局资源造成的,有时为了解
决此问题,优先考虑使用局部变量,退而求其次使用同步代码块,出于这样的安全考虑就必须牺牲
系统处理性能,加在多线程并发时资源挣夺最激烈的地方,这就实现了线程的同步机制
同步:A线程要请求某个资源,但是此资源正在被B线程使用中,因为同步机制存在,A线程请求
不到,怎么办,A线程只能等待下去
异步:A线程要请求某个资源,但是此资源正在被B线程使用中,因为没有同步机制存在,A线程
仍然请求的到,A线程无需等待
显然,同步最最安全,最保险的。而异步不安全,容易导致死锁,这样一个线程死掉就会导致整个
进程崩溃,但没有同步机制的存在,性能会有所提升
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的工作线程如下:
}
为了提高性能,在读或写原子数据的时候,应该避免使用同步,这个是非常危险而且错误的,原因参见线程同步的第二条
原子操作
atomic原子操作是CPU执行指令的最小单元,是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,在执行完毕之前不会被任何其它任务或事件中断。能够在单条指令中完成的操作都可以认为是" 原子操作",因为中断只能发生于指令之间。通常所说的原子操作包括对非long和double型的primitive进行赋值,以及返回这两者之外的primitive。如果你在long或double前面加了volatile,那么它就肯定是原子操作了。
线程同步
synchronized作用:
1. 互斥:保证一个线程里所看到的都是同一状态,不会出现一个线程执行过程中,共享数据被其他线程修改,引起状态转变,导致一个线程前后看到的东西处于不一致的状况。
2. 同步:保证在一个线程里所做的修改能够被其他线程所看到,避免由于JVM做如下代码优化,所导致多线程不能同步的问题。
while(!done)
i++;
JVM优化代码后转换成
if(!done)
while(true)
i++;
这样的话在另外一个线程修改了done可能会导致while循环永远不会退出,如果使用了synchronized,则不会做此优化,避免了此类问题的发生。
总结:当多个线程共享可变数据的时候,每个读或者写数据的线程都必须执行同步。如果只是为了同步(通信),而不是互斥访问,可以用volatile修饰变量,而不用synchronized方法,它可以保证在一个线程中读取的数据都是最新修改的,这样做可以提高性能,因为系统做同步的开销很大。
相关推荐
通过实例说明c#中同步和异步的区别,适合于初学者,能够帮助理解同步和异步的概念。
线程同步与异步套接字编程 线程同步与异步套接字编程线程同步与异步套接字编程
vc++ 线程同步与异步套接字编程实例,Windows套接字在两种模式下执行I/O操作,阻塞和非阻塞。在阻塞模式下,在I/O操作完成前,执行操作的Winsock函数会一直等待下去,不会立即返回程序(将控制权交还给程序)。而在非...
线程同步与异步套接字编程 线程同步与异步套接字编程
主要对C# 语言在1N ET 平台下进行多线程程序设计的方法进行探讨, 着重探讨了实现多线程同步与异步的步骤与方法, 并给出实现同步与异步的实例。
C++的线程同步与异步套接字编程源码.zip
visual c++ MFC之Lesson16线程同步与异步套接字编程
C#多线程同步与异步的实现[归纳].pdf
C#多线程同步与异步的实现.pdf
并发、多线程、同步异步概念的介绍。。。
进程线程通信,线程同步,异步,进程通信经典
vc 多线程实例,包括工作者线程和UI线程,以及线程的同步和异步。
C# 在vs2008下完美运行,通过AutoResetEvent,根据两个线程的运行时间,选择线程跟随或是线程交替,达到线程同步或是异步的目的。
摘要:VC/C++源码,系统相关,线程同步,套接字编程 VC++线程同步与异步套接字编程实例源码,
摘要:VC/C++源码,系统相关,线程同步,套接字 线程同步与异步套接字VC++编程实例,演示如何保证应用程序只有一个进程、线程死锁、基于消息的异步套接字实现,若要更细节的了解,请下载源码编译运行。
主要介绍了C++ 线程(串行 并行 同步 异步)详解的相关资料,需要的朋友可以参考下
1. SyncTaskExecutor:同步可以用SyncTaskExecutor,但这个可以说不算一个线程池,因为还在原线程执行。这个类没有实现异步调用,只是一个同步操作。 2.也可以用ThreadPoolTaskExecutor结合FutureTask做到同步。 3.2...
lettuce - 高级Java Redis客户端,用于线程安全同步,异步和reactive用法。 支持群集,Sentinel,管道和编解码器。
iOS线程同步方案,包括各种互斥锁,自旋锁,递归锁等深度解析!!!!
C#.net同步异步SOCKET通讯和多线程总结~