多线程同步java用哪种方法实现多线程同步比较好

多线程同步  时间:2021-07-13  阅读:()

多线程同步时几个的具体区别和应用场合?

1、 Event  用事件(Event)来同步线程是最具弹性的了。

一个事件有两种状态:激发状态和未激发状态。

也称有信号状态和无信号状态。

事件又分两种类型:手动重置事件和自动重置事件。

手动重置事件被设置为激发状态后,会唤醒所有等待的线程,而且一直保持为激发状态,直到程序重新把它设置为未激发状态。

自动重置事件被设置为激发状态后,会唤醒“一个”等待中的线程,然后自动恢复为未激发状态。

所以用自动重置事件来同步两个线程比较理想。

MFC中对应的类为CEvent.。

CEvent的构造函数默认创建一个自动重置的事件,而且处于未激发状态。

共有三个函数来改变事件的状态:SetEvent,ResetEvent和PulseEvent。

用事件来同步线程是一种比较理想的做法,但在实际的使用过程中要注意的是,对自动重置事件调用SetEvent和PulseEvent有可能会引起死锁,必须小心。

  多线程同步-event  在所有的内核对象中,事件内核对象是个最基本的。

它包含一个使用计数(与所有内核对象一样),一个BOOL值(用于指明该事件是个自动重置的事件还是一个人工重置的事件),还有一个BOOL值(用于指明该事件处于已通知状态还是未通知状态)。

事件能够通知一个线程的操作已经完成。

有两种类型的事件对象。

一种是人工重置事件,另一种是自动重置事件。

他们不同的地方在于:当人工重置的事件得到通知时,等待该事件的所有线程均变为可调度线程。

当一个自动重置的事件得到通知时,等待该事件的线程中只有一个线程变为可调度线程。

  当一个线程执行初始化操作,然后通知另一个线程执行剩余的操作时,事件使用得最频繁。

在这种情况下,事件初始化为未通知状态,然后,当该线程完成它的初始化操作后,它就将事件设置为已通知状态,而一直在等待该事件的另一个线程在事件已经被通知后,就变成可调度线程。

  当这个进程启动时,它创建一个人工重置的未通知状态的事件,并且将句柄保存在一个全局变量中。

这使得该进程中的其他线程能够非常容易地访问同一个事件对象。

程序一开始创建了三个线程,这些线程在初始化后就被挂起,等待事件。

这些线程要等待文件的内容读入内存,然后每个线程都会访问这段文件内容。

一个线程进行单词计数,另一个线程运行拼写检查,第三个线程运行语法检查。

这3个线程函数的代码的开始部分都相同,每个函数都调用WaitForSingleObject.,这将使线程暂停运行,直到文件的内容由主线程读入内存为止。

一旦主线程将数据准备好,它就调用SetEvent,给事件发出通知信号。

这时,系统就使所有这3个辅助线程进入可调度状态,它们都获得了C P U时间,并且可以访问内存块。

这3个线程都必须以只读方式访问内存,否则会出现内存错误。

这就是所有3个线程能够同时运行的唯一原因。

如果计算机上配有三个以上CPU,理论上这个3个线程能够真正地同时运行,从而可以在很短的时间内完成大量的操作  如果你使用自动重置的事件而不是人工重置的事件,那么应用程序的行为特性就有很大的差别。

当主线程调用S e t E v e n t之后,系统只允许一个辅助线程变成可调度状态。

同样,也无法保证系统将使哪个线程变为可调度状态。

其余两个辅助线程将继续等待。

已经变为可调度状态的线程拥有对内存块的独占访问权。

  让我们重新编写线程的函数,使得每个函数在返回前调用S e t E v e n t函数(就像Wi n M a i n函数所做的那样)。

  当主线程将文件内容读入内存后,它就调用SetEvent函数,这样操作西永就会使这三个在等待的线程中的一个成为可调度线程。

我们不知道系统将首先选择哪个线程作为可调度线程。

当该线程完成操作时,它也将调用S e t E v e n t函数,使下一个被调度。

这样,三个线程会以先后顺序执行,至于什么顺序,那是操作系统决定的。

所以,就算每个辅助线程均以读/写方式访问内存块,也不会产生任何问题,这些线程将不再被要求将数据视为只读数据。

  这个例子清楚地展示出使用人工重置事件与自动重置事件之间的差别。

  P u l s e E v e n t函数使得事件变为已通知状态,然后立即又变为未通知状态,这就像在调用S e t E v e n t后又立即调用R e s e t E v e n t函数一样。

如果在人工重置的事件上调用P u l s e E v e n t函数,那么在发出该事件时,等待该事件的任何一个线程或所有线程将变为可调度线程。

如果在自动重置事件上调用P u l s e E v e n t函数,那么只有一个等待该事件的线程变为可调度线程。

如果在发出事件时没有任何线程在等待该事件,那么将不起任何作用[2]。

  2、 Critical Section  使用临界区域的第一个忠告就是不要长时间锁住一份资源。

这里的长时间是相对的,视不同程序而定。

对一些控制软件来说,可能是数毫秒,但是对另外一些程序来说,可以长达数分钟。

但进入临界区后必须尽快地离开,释放资源。

如果不释放的话,会如何?答案是不会怎样。

如果是主线程(GUI线程)要进入一个没有被释放的临界区,呵呵,程序就会挂了!临界区域的一个缺点就是:Critical Section不是一个核心对象,无法获知进入临界区的线程是生是死,如果进入临界区的线程挂了,没有释放临界资源,系统无法获知,而且没有办法释放该临界资源。

这个缺点在互斥器(Mutex)中得到了弥补。

Critical Section在MFC中的相应实现类是CcriticalSection。

CcriticalSection::Lock()进入临界区,CcriticalSection::UnLock()离开临界区。

  3、 Mutex  互斥器的功能和临界区域很相似。

区别是:Mutex所花费的时间比Critical Section多的多,但是Mutex是核心对象(Event、Semaphore也是),可以跨进程使用,而且等待一个被锁住的Mutex可以设定TIMEOUT,不会像Critical Section那样无法得知临界区域的情况,而一直死等。

MFC中的对应类为CMutex。

Win32函数有:创建互斥体CreateMutex() ,打开互斥体OpenMutex(),释放互斥体ReleaseMutex()。

Mutex的拥有权并非属于那个产生它的线程,而是最后那个对此Mutex进行等待操作(WaitForSingleObject等等)并且尚未进行ReleaseMutex()操作的线程。

线程拥有Mutex就好像进入Critical Section一样,一次只能有一个线程拥有该Mutex。

如果一个拥有Mutex的线程在返回之前没有调用ReleaseMutex(),那么这个Mutex就被舍弃了,但是当其他线程等待(WaitForSingleObject等)这个Mutex时,仍能返回,并得到一个WAIT_ABANDONED_0返回值。

能够知道一个Mutex被舍弃是Mutex特有的。

  4、 Semaphore  信号量是最具历史的同步机制。

信号量是解决producer/consumer问题的关键要素。

对应的MFC类是Csemaphore。

Win32函数CreateSemaphore()用来产生信号量。

ReleaseSemaphore()用来解除锁定。

Semaphore的现值代表的意义是目前可用的资源数,如果Semaphore的现值为1,表示还有一个锁定动作可以成功。

如果现值为5,就表示还有五个锁定动作可以成功。

当调用Wait…等函数要求锁定,如果Semaphore现值不为0,Wait…马上返回,资源数减1。

当调用ReleaseSemaphore()资源数加1,当时不会超过初始设定的资源总数。

线程同步几种方式

线程有可能和其他线程共享一些资源,比如,内存,文件,数据库等。

当多个线程同时读写同一份共享资源的时候,可能会引起冲突。

这时候,我们需要引入线程“同步”机制,即各位线程之间要有个先来后到,不能一窝蜂挤上去抢作一团。

线程同步的真实意思和字面意思恰好相反。

线程同步的真实意思,其实是“排队”:几个线程之间要排队,一个一个对共享资源进行操作,而不是同时进行操作。

线程同步的方法 (1)wait():使一个线程处于等待状态,并且释放所持有的对象的lock。

(2)sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉 interruptedexception异常。

(3)notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的 唤醒某一个等待状态的线程,而是由jvm确定唤醒哪个线程,而且不是按优先级。

(4)notityall ():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁, 而是让它们竞争

JAVA 多线程同步概念

加入一个程序里的一个方法有以下输出,这两个输出需要一起执行: println("第"+i+"个线程连接"); println("你好啊,"+i+"号"); 然后有两个线程连调用了这个方法,分别叫他们1和2线程 本来我想要的输出应该是: 第1个线程连接 你好啊,1号 第2个线程连接 你好啊,2号 但是如果不加同步的话,极有可能导致如下输出: 第1个线程连接 第2个线程连接 你好啊,2号 你好啊,1号 这显然不是我想要的。

再比如银行系统,个人账户的存、取操作也应该是同步的 如果我的余额是10元,我想在线买一个15元的东西,我的余额不足,于是我充值5元,再消费15元。

由于操作的目标都是余额属性,所以多线程不同步的情况下,极有可能是先执行了消费操作后执行存钱操作。

这种情况下我的余额是不足的,导致操作不成功。

但事实是,在他判定我余额的后一秒钟存钱动作执行了,其实我的余额是够的。

这就导致了一个错误。

同步锁只是保证执行顺序,而不是说这一个方法大家在排队

什么是线程的同步?为什么要实现线程的同步?

线程同步:是多个线程同时访问同一资源,等待资源访问结束,浪费时间,效率低 线程异步:访问资源时在空闲等待时同时访问其他资源,实现多线程机制 异步处理就是,你现在问我问题,我可以不回答你,等我用时间了再处理你这个问题.同步不就反之了,同步信息被立即处理 -- 直到信息处理完成才返回消息句柄;异步信息收到后将在后台处理一段时间 -- 而早在信息处理结束前就返回消息句柄 区别同步和异步 一个进程启动的多个不相干线程,它们相互之间关系为异步。

同步必须执行到底之后才能执行其他操作,而异步可以任意操作 同步的好处与弊端 好处:解决了线程的安全问题。

弊端:每次都有判断锁,降低了效率。

但是在安全与效率之间,首先考虑的是安全。

同步的前提 一、多个线程执行的时候需要同步,如果是单线程则不需要同步。

二、多个线程在执行的过程中是不是使用同一把锁。

如果是,就是同步。

否则不是同步。

synchronzied(obj){ }同一个所 synchronzied(new Object){ } 不是同一个锁 对run()中需要同步的代码进行同步,如果有的32313133353236313431303231363533e78988e69d8331333365653762代码不需要同步,则不要放到同步代码块中去。

同步的表现形式有两种: 1、同步代码块,被同步关键字封装的代码就是同步代码块; 2、同步函数,被同步关键字修饰的函数就是同步函数。

同步代码块的锁是可以是任意对象,在执行之前就好创建好一个锁对象。

那么同步函数的锁在哪里? 同步函数的锁就是调用该同步函数的对象,也就是this。

如果同步函数被static修饰,那么该同步函数的锁就是这个类在堆内存中形成的类文件对象。

这时候不一定有该类的对象,但一定有该类的字节码文件对象。

java用哪种方法实现多线程同步比较好

Java中的同步机制有四种:① ThreadLocal ② synchronized( ) ③ wait() 与 notify() ④ volatile 目的:都是为了解决多线程中的对同一变量的访问冲突 (1)ThreadLocal 保证不同线程拥有不同实例,相同线程一定拥有相同的实例,即为每一个使用该变量的线程提供一个该变量值的副本,每一个线程都可以独立改变自己的副本,而不是与其它线程的副本冲突。

(2)优势:提供了线程安全的共享对象 (3)与其它同步机制的区别:同步机制是为了同步多个线程对相同资源的并发访问,是为了多个线程之间进行通信;而 ThreadLocal 是隔离多个线程的数据共享,从根本上就不在多个线程之间共享资源,这样当然不需要多个线程进行同步了。

(4)使用技巧:需要多个线程之间进行通信,使用同步机制;如果需要隔离多个线程之间的共享冲突,推荐使用 ThreadLocal (线程安全)。

华纳云E5处理器16G内存100Mbps688元/月

近日华纳云商家正式上线了美国服务器产品,这次美国机房上线的产品包括美国云服务器、美国独立服务器、美国高防御服务器以及美国高防云服务器等产品,新产品上线华纳云推出了史上优惠力度最高的特价优惠活动,美国云服务器低至3折,1核心1G内存5Mbps带宽低至24元/月,20G ddos高防御服务器低至688元/月,年付周期再送2个月、两年送4个月、三年送6个月,终身续费同价,有需要的朋友可以关注一下。华纳云...

3G流量免费高防CDN 50-200G防御

简介酷盾安全怎么样?酷盾安全,隶属于云南酷番云计算有限公司,主要提供高防CDN服务,高防服务器等,分为中国境内CDN,和境外CDN和二个产品,均支持SSL。目前CDN处于内测阶段,目前是免费的,套餐包0.01一个。3G流量(高防CDN)用完了继续续费或者购买升级包即可。有兴趣的可以看看,需要实名的。官方网站: :点击进入官网云南酷番云计算有限公司优惠方案流量3G,用完了不够再次购买或者升级套餐流量...

云基最高500G DDoS无视CC攻击(Yunbase),洛杉矶CN2GIA、国内外高防服务器

云基成立于2020年,目前主要提供高防海内外独立服务器用户,欢迎各类追求稳定和高防优质线路的用户。业务可选:洛杉矶CN2-GIA+高防(默认500G高防)、洛杉矶CN2-GIA(默认带50Gbps防御)、香港CN2-GIA高防(双向CN2GIA专线,突发带宽支持,15G-20G DDoS防御,无视CC)、国内高防服务器(广州移动、北京多线、石家庄BGP、保定联通、扬州BGP、厦门BGP、厦门电信、...

多线程同步为你推荐
开票系统金税盘开票系统怎么用最开放的浏览器用的最多的三个浏览器是?天融信防火墙都说天融信的产品不错,那天融信的下一代防火墙真的是当今最好的防火墙产品了吗?调度系统现在有很多人说同城调度系统,这是用来干嘛的呀?索引超出了数组界限索引超出了数组界限是怎么回事啊?radius认证电信或网通的RADIUS认证都记录些什么?谁能说说ISP的宽带帐号检查流程国际加速世界经济全球化加速发展的表现有哪些?在全球化趋势加强的过程中,人类共同面临的问题有哪些?新手怎么制作表格怎么制作表格?screencapture电脑qq问题:点击qq邮箱与空间,弹出Screen Capture Control 进入不了qq邮箱与空间,怎么解决?toolstripc#中 (ToolStrip)控件是做什么用的?
中国十大域名注册商 北京域名空间 荷兰vps vir 阿里云搜索 vpsio pccw 外贸主机 腾讯云数据库 美国仿牌空间 美国php空间 debian7 qq数据库 毫秒英文 工信部icp备案号 爱奇艺vip免费领取 360云服务 美国凤凰城 沈阳主机托管 摩尔庄园注册 更多