多线程同步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 (线程安全)。

注册做什么96%可以干啥,常用的7个常用的国内国外域名注册服务商_云服务器可以干什么

日前,国内知名主机服务商阿里云与国外资深服务器面板Plesk强强联合,推出 阿里云域名注册与备案、服务器ECS购买与登录使用 前言云服务器(Elastic  只需要确定cpu内存与带宽基本上就可以了,对于新手用户来说,我们在购买阿里云服务申请服务器与域名许多云服务商的云服务器配置是弹性的 三周学会小程序第三讲:服务 不过这个国外服务器有点慢,可以考虑国内的ngrokcc。 ngrokcc...

企鹅小屋:垃圾服务商有跑路风险,站长注意转移备份数据!

企鹅小屋:垃圾服务商有跑路风险!企鹅不允许你二次工单的,二次提交工单直接关服务器,再严重就封号,意思是你提交工单要小心,别因为提交工单被干了账号!前段时间,就有站长说企鹅小屋要跑路了,站长不太相信,本站平台已经为企鹅小屋推荐了几千元的业绩,CPS返利达182.67CNY。然后,站长通过企鹅小屋后台申请提现,提现申请至今已经有20几天,企鹅小屋也没有转账。然后,搞笑的一幕出现了:平台账号登录不上提示...

gcorelabs:CDN业务节点分布100多个国家地区,免费版提供1T/月流量

卢森堡商家gcorelabs是个全球数据中心集大成的运营者,不但提供超过32个数据中心的VPS、13个数据中心的cloud(云服务器)、超过44个数据中心的独立服务器,还提供超过100个数据中心节点的CDN业务。CDN的总带宽容量超过50Tbps,支持免费测试! Gcorelabs根据业务分,有2套后台,分别是: CDN、流媒体平台、DDoS高防业务、块存储、cloud云服务器、裸金属服务器...

多线程同步为你推荐
1u1U的 定义bloomfilter电脑游戏图像设置里的Bloom是什么意思?foxmail邮箱注册如何注册一个foxmail邮箱rdlcordless phone是什么意思bindserviceonserviceconnected什么时候执行调度系统配送调度系统是干嘛的?是手机还是电脑的系统?spawning急救!编好C++程序后(确认无误),再编译时总出现error spawning 是什么意思?是不是系统出了问题有b吗34B的胸围有多大?mediasres什么意思新手怎么制作表格我是初学者、电脑上怎么制作表格
网通服务器租用 域名查询工具 vps教程 linuxapache虚拟主机 花生壳域名贝锐 com域名抢注 域名商 Vultr 论坛空间 域名评估 免费防火墙 qq对话框 数据库空间 云服务器比较 如何登陆阿里云邮箱 ssl加速 双十二促销 九零网络 windowsserver2008r2 winserver2008r2 更多