当前位置: 首页 > wzjs >正文

淄博网站建设专家中国企业培训网

淄博网站建设专家,中国企业培训网,环保政府网站建设目的意义,北京公安网站备案系统线程锁是多线程并发共享数据,保证一致性的工具。多线程可以同时运行多个任务但是当多个线程同时访问共享数据时,可能导致数据不同步。当有多个线程访问同一对象的加锁方法或代码块时,同一时间只有一个线程在执行,其余线程必须要等…

线程锁是多线程并发共享数据,保证一致性的工具。多线程可以同时运行多个任务但是当多个线程同时访问共享数据时,可能导致数据不同步。当有多个线程访问同一对象的加锁方法或代码块时,同一时间只有一个线程在执行,其余线程必须要等待当前线程执行完之后才能执行该代码段。但其余线程是可以访问该对象中的非加锁代码块的。以下介绍.NET(C#)中 lock 和 ReaderWriterLock 的使用。

 

1、lock 和 ReaderWriterLock

lock 语句获取给定对象的互斥 lock,执行语句块,然后释放 lock。 持有 lock 时,持有 lock 的线程可以再次获取并释放 lock。 阻止任何其他线程获取 lock 并等待释放 lockReaderWriterLock支持单个写线程和多个读线程的锁。.NET Framework 有两个读取器-编写器锁, ReaderWriterLockSlimReaderWriterLock 。 建议对所有新开发的项目使用 ReaderWriterLockSlim。 虽然 ReaderWriterLockSlim 类似于 ReaderWriterLock,但不同之处在于,前者简化了递归规则以及锁状态的升级和降级规则。 ReaderWriterLockSlim 避免了许多潜在的死锁情况。 另外,ReaderWriterLockSlim 的性能显著优于 ReaderWriterLockReaderWriterLock长时间持有读取器锁或写入器锁将枯竭其他线程。 为了获得最佳性能,请考虑重构应用程序以最大程度地缩短写入的持续时间。

lock的使用语法:

lock (x)
{// 加锁代码
}

 lock是语法糖,代码相当于:

object __lockObj = x;
bool __lockWasTaken = false;
try
{System.Threading.Monitor.Enter(__lockObj, ref __lockWasTaken);// 加锁代码
}
finally
{if (__lockWasTaken) System.Threading.Monitor.Exit(__lockObj);
}

 

注意:无论lock锁定的是this,还是obj,只要关心多线程锁定的对象是不是为同一个对象。当同步对共享资源的线程访问时,最好使用锁定专用对象实例(例如,private readonly object balanceLock = new object();),避免对不同的共享资源使用相同的 lock 对象实例,因为这可能导致死锁或锁争用。最好避免使用this、Type 实例、字符串实例作为lock锁定的对象。

2、lock的使用

lock为互斥锁,lock 关键字将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁。当任何一个线程获取到锁后,其他线程如果需要使用该临界区内代码,则必须等待前一个线程使用完毕后释放锁。

例如,

using System;
using System.Threading.Tasks;
namespace ConsoleApplication
{class Program{static void Main(){var account = new Account(1000);var tasks = new Task[100];for (int i = 0; i < tasks.Length; i++){tasks[i] = Task.Run(() => Update(account));}Task.WhenAll(tasks).Wait();Console.WriteLine($"Account balance : {account.GetBalance()}");Console.ReadKey();}static void Update(Account account){decimal[] amounts = { 0, 2, -3, 6, -2, -1, 8, -5, 11, -6 };foreach (var amount in amounts){if (amount >= 0){account.Credit(amount);}else{account.Debit(Math.Abs(amount));}}}}public class Account{private readonly object balanceLock = new object();private decimal balance;public Account(decimal initialBalance) => balance = initialBalance;public decimal Debit(decimal amount){if (amount < 0){throw new ArgumentOutOfRangeException(nameof(amount), "The debit amount cannot be negative.");}decimal appliedAmount = 0;lock (balanceLock){if (balance >= amount){balance -= amount;appliedAmount = amount;}}return appliedAmount;}public void Credit(decimal amount){if (amount < 0){throw new ArgumentOutOfRangeException(nameof(amount), "The credit amount cannot be negative.");}lock (balanceLock){balance += amount;}}public decimal GetBalance(){lock (balanceLock){return balance;}}}
}

 

3、ReaderWriterLock的使用

ReaderWriterLock为读写锁,ReaderWriterLock 定义支持单个写线程和多个读线程的锁。该锁主要是解决并发读的性能问题,使用该锁可以大大提高数据并发访问的性能,只有在写时,才会阻塞所有的读锁。建议对所有新开发的项目使用 ReaderWriterLockSlim。 虽然 ReaderWriterLockSlim 类似于 ReaderWriterLock,但不同之处在于,前者简化了递归规则以及锁状态的升级和降级规则。 ReaderWriterLockSlim 避免了许多潜在的死锁情况。 另外,ReaderWriterLockSlim 的性能显著优于 ReaderWriterLock

例如,

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication
{class Program{static ReaderWriterLock rwl = new ReaderWriterLock();// 定义ReaderWriterLock对象。static int resource = 0;const int numThreads = 8;static bool running = true;static int readerTimeouts = 0;static int writerTimeouts = 0;static int reads = 0;static int writes = 0;public static void Main(){// 启动多个线程,对共享资源进行随机读写。Thread[] t = new Thread[numThreads];for (int i = 0; i < numThreads; i++){t[i] = new Thread(new ThreadStart(ThreadProc));t[i].Name = new String(Convert.ToChar(i + 65), 1);t[i].Start();if (i > 10)Thread.Sleep(300);}// 等待它们全部完成。running = false;for (int i = 0; i < numThreads; i++)t[i].Join();Console.WriteLine("\nread:{0} , write:{1} , reader time-out:{2}, writer time-out:{3}",reads, writes, readerTimeouts, writerTimeouts);Console.Write("Press ENTER to exit... ");Console.ReadLine();}static void ThreadProc(){Random rnd = new Random();//随机选择线程对共享资源进行读写的方式。while (running){double action = rnd.NextDouble();if (action < .8)ReadFromResource(10);else if (action < .81)ReleaseRestore(rnd, 50);else if (action < .90)UpgradeDowngrade(rnd, 100);elseWriteToResource(rnd, 100);}}// 请求和释放读取锁,并处理超时。static void ReadFromResource(int timeOut){try{rwl.AcquireReaderLock(timeOut);try{// 这个线程从共享资源读取是安全的。Display("reads resource value :" + resource);Interlocked.Increment(ref reads);}finally{// 确保锁已释放。rwl.ReleaseReaderLock();}}catch (ApplicationException){// 读取锁定请求超时处理Interlocked.Increment(ref readerTimeouts);}}// 请求和释放写入锁,并处理超时static void WriteToResource(Random rnd, int timeOut){try{rwl.AcquireWriterLock(timeOut);try{// 这个线程从共享资源访问是安全的resource = rnd.Next(500);Display("writes resource value " + resource);Interlocked.Increment(ref writes);}finally{// 确保锁已释放rwl.ReleaseWriterLock();}}catch (ApplicationException){// 写锁请求超时处理Interlocked.Increment(ref writerTimeouts);}}// 请求读取锁,将读取锁升级为写入锁,然后再次将其降级为读取锁。static void UpgradeDowngrade(Random rnd, int timeOut){try{rwl.AcquireReaderLock(timeOut);try{// 这个线程从共享资源读取是安全的Display("reads resource value " + resource);Interlocked.Increment(ref reads);//要写资源,要么释放读锁,要么请求写锁,或升级读锁升级//读取锁将线程放入写队列中,在any后面可能正在等待写入锁的其他线程。try{LockCookie lc = rwl.UpgradeToWriterLock(timeOut);try{//对这个线程来说,从共享资源读写是安全的。resource = rnd.Next(500);Display("writes resource value " + resource);Interlocked.Increment(ref writes);}finally{// 确保锁已释放。rwl.DowngradeFromWriterLock(ref lc);}}catch (ApplicationException){// 事件解释升级请求超时。Interlocked.Increment(ref writerTimeouts);}// 如果锁被降级,从资源中读取仍然是安全的。Display("reads resource value: " + resource);Interlocked.Increment(ref reads);}finally{// 确保锁已释放rwl.ReleaseReaderLock();}}catch (ApplicationException){// 读取锁定请求超时处理步骤Interlocked.Increment(ref readerTimeouts);}}//释放所有锁,之后恢复锁状态。//使用序列号来确定另一个线程是否有//获得了一个写锁,因为该线程最后一次访问资源。static void ReleaseRestore(Random rnd, int timeOut){int lastWriter;try{rwl.AcquireReaderLock(timeOut);try{//线程从共享资源中读取数据是安全的,//读取和缓存资源的值。int resourceValue = resource;     // 缓存资源值。Display("reads resource value " + resourceValue);Interlocked.Increment(ref reads);// 保存当前写入器序列号。lastWriter = rwl.WriterSeqNum;// 释放锁并保存一个cookie,以便稍后可以恢复锁。LockCookie lc = rwl.ReleaseLock();// 等待一个随机的时间间隔,然后恢复之前的锁状态。Thread.Sleep(rnd.Next(250));rwl.RestoreLock(ref lc);//检查其他线程是否在这个时间间隔内获得写锁。//如果不是,则资源的缓存值仍然有效。if (rwl.AnyWritersSince(lastWriter)){resourceValue = resource;Interlocked.Increment(ref reads);Display("resource has changed: " + resourceValue);}else{Display("resource has not changed: " + resourceValue);}}finally{// 确保锁已释放。rwl.ReleaseReaderLock();}}catch (ApplicationException){// 读取锁定请求超时处理Interlocked.Increment(ref readerTimeouts);}}static void Display(string msg){Console.Write("Thread {0} {1}.       \r", Thread.CurrentThread.Name, msg);}}
}

 

http://www.dtcms.com/wzjs/319861.html

相关文章:

  • 做微信小程序是不是不用做网站推广文章的注意事项
  • 建筑装饰公司做网站的作用seo关键词优化
  • 谷城网站建设网络培训心得体会5篇
  • wordpress上传文件路径成都网站优化平台
  • 搭建公司网站费用国内好的seo
  • 哪家公司做网站专业百度收录在线提交
  • 网站模板免费下载php视频广告联盟平台
  • php 网站建设流程外贸企业网站设计公司
  • 怎样查看网站日志文件百度工具seo
  • wordpress关闭某个栏目上海关键词优化方法
  • 网站建设中正在为您转博客seo优化技术
  • 青海省住房和城乡建设局网站十大短视频平台排行榜
  • wordpress仿站教程网网站收录查询工具
  • 内部购物券网站怎么做ping站长工具
  • 广州建站招聘拼多多seo是什么意思
  • 创建网站是怎么赚钱的使用软件提高百度推广排名
  • 泉州网站关键词推广费用自己怎么制作网页
  • 建设工程类公司网站重庆森林百度网盘
  • 哪里有工程做的网站西安百度关键词排名服务
  • 外贸网站建设制作西安网络公司
  • 网站建设制作服务商百度怎么发免费广告
  • 网站设湖人最新排名最新排名
  • 做视频素材哪个网站好头条今日头条
  • 上海网安网站建设关键词优化推广公司排名
  • 建设企业查询网站武汉seo网站推广培训
  • wordpress物流插件宁波seo公司哪家好
  • 网站设计 手写济南特大最新消息
  • 网站建设费用如何入账电商网站大全
  • 台州网站搜索引擎优化广州信息流推广公司排名
  • 个人域名可以做网站吗让百度收录自己的网站