线程同步和并发
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程同步和并发相关的知识,希望对你有一定的参考价值。
参考技术A 每个线程都有自己的高速缓存,在多线并发过程中,会导致CPU访问到高速缓存的数据不一致,从而导致线程并发问题。volatile本质是:jvm当前变量在寄存器中的值是不确定的,需要从主存中读取
lock锁的状态是可见的,lock锁的类型比较多:可重入锁,读写锁,使用方法更加灵活。lock必须在finally释放,否则可能会造成异常情况下,锁无法释放
ConcurrentHashMap BlockingQueue等数据结构
在java中,由于hashmap等容器是非线程安全的,java提供对用concurrentXXX数据结构,多线程安全,而且效率非常高,有兴趣的同事可以去看下
ThreadLocal比较常用,其本质不是线程同步,而是以空间换时间,每个线程维护自己的副本(在后台并发时比较有用)
测试:
结果:
其原因是ThreadLocal在ThreadLocalMap中为每个线程保存了副本,map的key就是Thread本身,ThreadLocalMap持有ThreadLocal的弱引用,保证线程释放资源时的内存泄露问题(ThreadLoacl变量建议设置成private static),ThreadLocal:
多线程进程并发并行同步异步伪并发真并发
进程、线程
1、进程
一个程序,可以独立运行的一段程序。系统对它进行资源分配和调度。
2、线程
进程的基本单位,对它进行cpu分配和调度。只拥有一点在运行中必不可少的资源(寄存器,栈,程序计数器)
3、线程与进程的联系与区别
联系:
(1)线程是指进程内的一个执行单元,一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程(通常说的主线程)。 但是存在 DOS 这样的单进程(而且无线程概念)系统。
(2)资源分配给进程,同一进程的所有线程共享该进程的所有资源,线程自己基本上不拥有系统资源。
(3)处理机分给线程,即真正在处理机上运行的是线程。
(4) 线程的改变只代表了 CPU 执行过程的改变,而没有发生进程所拥有的资源变化。
区别:
(1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位。
(2)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进
程的资源。
共有特性:
(3)并发性:进程之间可以并发执行,同一个进程的多个线程之间也可以并发执行。
4、同一进程下,线程与线程之间的联系
(1)进程可创建多个线程来执行同一程序的不同部分。
(2) 一个线程可以创建和撤消另一个线程,同一个进程中的多线程之间可以并发执行
(3)线程在执行过程中,需要协作同步,不同进程的线程间要利用消息通信的办法实现同步。 (为什么要同步:见同步举例)
(4)充分发挥多处理器的功能。通过创建多线程进程,每个线程在一个处理器上运行,从而实现应用程序的并发性,使每个处理器都得到充分运行。
线程之间同步举例:
假设有一个程序,其中一个线程用于把文件读到内存,而另一个线程用于统计文件中的字符数。当然,在把整个文件调入内存之前,统计它的计数是没有意义的。由于是不同进程里的线程,操作系统会把两个线程当作是互不相干的任务分别执行,这样就可能在没有把整个文件装入内存时统计字数。为解决此问题,你必须使两个线程同步工作。
其它:
在网络或多用户环境下,一个服务器通常需要接收大量且不确定数量用户的并发请求,为每一个请求都创建一个进程显然是行不通的,——无论是从系统资源开销方面或是响应用户请求的效率方面来看。
线程可以有效地提高系统的执行效率,但并不是在所有计算机系统中都是适用的,如某些很少做进程调度和切换的实时系统。使用线程的好处是有多个任务需要处理机处理时,减少处理机的切换时间;而且,线程的创建和结束所需要的系统开销也比进程的创建和结束要小得多。最适用使用线程的系统是多处理机系统和网络系统或分布式系统。
并行、并发
解释一:并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔发生。
解释二:并行是在不同实体上的多个事件,并发是在同一实体上的多个事件。
解释三:在一台处理器上"同时"处理多个任务,在多台处理器上同时处理多个任务。如hadoop分布式集群
进程的并发和并行与线程的并发和并行:
进程的并发:
并发的关键是你有处理多个任务的能力,不一定要同时执行。在操作系统中cpu只能并发处理进程(存在多个进行,但是是轮流执行的),不能并行。
并行的关键是能同时处理多个任务。
线程的并发和并行:(线程跟处理器联系在一起)
在进程可以同时拥有两个或者多个线程。如果程序在单核处理器上运行,那么这两个线程将交替地换入或者换出内存。这些线程是并发的——每个线程都处于执行过程中的某个状态。
如果程序能够同时执行,那么就一定是运行在多核处理器上。此时,程序中的每个线程都将分配到一个独立的处理器核上,此时他们是并行的。
"并行"概念是"并发"概念的一个子集。也就是说,你可以编写一个拥有多个线程或者进程的并发程序,但如果没有多核处理器来执行这个程序,那么就不能以并行方式来运行代码。
同步、异步
仅针对js语言:
示例场景:同步请求与异步请求
同步请求:发起请求,然后等待,当执行完请的回调函数才继续执行请求代码块之后的代码,如果一直没又响应,会阻塞请求代码块后面代码的执行。
异步请求:发起请求,继续执行请求代码块之后的代码,不会阻塞请求代码块后面代码的执行,当请求被响应时,系统会通知进程处理。这样提高执行效率。
多线程和异步
比如js里是单线程的,里面用异步当时。所以在这里异步和线程不在一个层面的上。
异步和多线程两者都可以达到避免调用线程阻塞的目的,从而提高软件的可响应性。甚至有些时候就认为异步和多线程是等同的概念。但是,异步和多线程还是有一些区别的。而这些区别造成了使用异步和多线程的时机的区别。
cpu层面谈区别:
CPU的异步处理:DMA——直 接内存访问的意思,拥有DMA功能的硬件在和内存进行数据交换的时候可以不消耗CPU资源和时间。只要CPU在发起数据传输时发送一个指令,硬件就开 始自己和内存交换数据,在传输完成之后硬件会触发一个中断来通知操作完成。是等待执行的
多线程:线程本质上是进程中一段并发运行的代码,线程需要操作系统投入CPU资源来运行和调度。
这个要多个处理器处理才能实现多线程,这些线程是同时执行的。
从执行时机来看,就不是同一个概念
在js里来谈:
多线程即要同时处理多个事件,但是js是顺序执行的,所以即使是对同一行为,也根据事件注册的先后顺序去触发事件,这就不存在多线程。
异步是在处理一个事件的同时,等待的某个事件被触发了,也会执行,是同时处理多个事件
比如页面一直在倒计时,这时候某个数据回来,执行的函数是去渲染页面的某个部分,这时是即在倒计时也在渲染。可以这样举例吗?
适用范围(不知道该从什么层面来讲,感觉不同层面不同的优缺点)
当需要执行I/O操作时,使用异步操作比使用线程+同步 I/O操作更合适。I/O操作不仅包括了直接的文件、网络的读写,还包括数据库操作、Web Service、HttpRequest以及.net Remoting等跨进程的调用。
而线程的适用范围则是那种需要长时间CPU运算的场合,例如耗时较长的图形处理和算法执行。但是往往由于使用线程编程的简单和符合习惯,所以很多朋友往往会使用线程来执行耗时较长的I/O操作。这样在只有少数几个并发操作的时候还无伤大雅,如果需要处理大量的并发操作时就不合适了。
伪并发和真并发
伪并发是指单核处理器的并发。
真并发是指多核处理器的并发。
以上是关于线程同步和并发的主要内容,如果未能解决你的问题,请参考以下文章