.NET简谈组件程序设计之(上下文与同步域)

我们继续学习.NET多线程技术,这篇文章的内容可能有点复杂。在打破常理之后,换一种新的思考模型最为头疼。这篇文章里面会涉及到一些不太常见的概念,比如:上下文、同步域等等。我也是最近才接触这些关于组件编程方面的高深技术,大家一起学习,再大的困难也是有时间限制的,只要我们坚持。

在本人的上一篇文章“.NET简谈组件程序设计之(多线程与并发管理一)”中,只是初步的带领我们学习一下关于多线程的一些基本的原理,包括线程切换,线程的开始、执行、等待、结束。

这篇文章的重点是学习关于线程的同步、互斥的机制。在多线程的应用程序中,最少会有一个主线程在运行着,如果我们想提高应用程序的吞吐量就必须借助多线程的原理来实现。[王清培版权所有,转载请给出署名]

.NET上下文(ContextBoundObject对象)

什么叫上下文,千万别和ASP.NET中的上下文搞混了,这个上下文是个形容词,在不同的场合有不同的意思。在ASP.NET中的上下文是指Context对象,这个对象基本上包容了HTTP协议的整个生命周期的信息,可以获取到客户端浏览器的一些基本信息,也可以获取到关于HTTP协议的一些信息,等等。

这里所讲的上下文是.NET程序执行的最小逻辑范围,ASP.NET上下文是站在B/S编程模型角度去看待的,而这里的上下文是站在.NET底层运行角度看来的,后者是代码的上下文,前者是整个生命周期的上下文。

在没有接触ContextBoundObject之前我一直以为.NET程序执行的最小逻辑范围是应用程序域(AppDomain),知道了之后才知道另有隐情,上下文是用来确定对象的逻辑归属,在多线程(Thread)、事物处理(Transaction)、企业服务(Enterprise)等方面都需要用上下文来对对象进行规划。下面您将看到怎么用上下文来进行线程的同步的。

图1:

.NET同步域(Synchronization特性)

同步域的概念是来源于多线程的场合,在我们进行多线程操作的时候,让很多个线程去同时访问一个内存对象的时候,是必须用锁来保证只有一个线程进入对象操作的,那么同步域的概念就是同步的是一个区域,而不是单单的一个对象。

线程是代码的执行路径,只要在这条执行路径上都属于线程的范围,那么怎么在执行的路径中分离出另外一个同步区域。[王清培版权所有,转载请给出署名]

临界资源是系统中对同一时间只能由一个线程进行访问的描述。我们假设自己就是一个线程,我们要去家里拿点东西,那么门就是线程的同步锁,当我们进去的时候就把门从里面反锁,出去的时候就把门打开,以方便自己的家人进来。这个房子就是临界资源。可能这样的描述不太靠谱,哪有这样的家啊!

图2:

利用上下文和同步域进行线程的同步

下面我们将结合上下文和同步域的原理进行线程的同步。请看一段代码:

 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4. using System.Threading;  
  5. using System.Runtime.Remoting;  
  6. using System.Runtime.Remoting.Contexts;  
  7.  
  8. namespace ConsoleApplication1.多线程和并发管理  
  9. {  
  10.     //如果不加上下文,那么就是以对象为线程锁定区域,如果加上下文,那么就是已逻辑上下文为锁定区域  
  11.     [Synchronization(SynchronizationAttribute.REQUIRED, true)]//重新进入同步域  
  12.     public class MyClass : ContextBoundObject  
  13.     {  
  14.         public void DoWork()  
  15.         {  
  16.  
  17.             int i = 0;  
  18.             while (true)  
  19.             {  
  20.                 Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "|" + i++);  
  21.                 if (i == 10)  
  22.                 {  
  23.                     Console.WriteLine("---------------------------------------------");  
  24.                     Console.Read();  
  25.                     break;  
  26.                 }  
  27.             }  
  28.  
  29.         }  
  30.     }  
  31. }  

在这段代码里面,我给Myclass类加上了Synchronization特性,并且继承自上下文对象ContextBoundObject。两者必须集合使用,同步域只有在上下文中才有效。

【MSDN:将 SynchronizationAttribute 应用到一个上下文绑定对象会导致创建等待句柄和自动重置事件,这些内容不一定会被作为垃圾来回收。因此,不要在很短的时间内创建大量用 SynchronizationAttribute 标记的上下文绑定对象。】

图3:

 

图4:

我们来看调用代码:

 
  1. Thread currentthread = Thread.CurrentThread;  
  2.             Console.WriteLine(currentthread.Name + currentthread.ManagedThreadId);  
  3.  
  4.             MyClass myclass = new MyClass();  
  5.  
  6.             Thread thread = new Thread(new ThreadStart(myclass.DoWork));  
  7.  
  8.  
  9.             Thread thread2 = new Thread(new ThreadStart(myclass.DoWork));  
  10.             thread2.Start();  
  11.             thread.Start();  
  12.  
  13.             thread2.Join();  
  14.             thread.Join();  
  15.             Console.WriteLine(currentthread.Name + currentthread.ManagedThreadId);  
  16.             Console.Read(); 

图5:

我为了方便截图所以把循环的数字设的比较小,如果你想测试一下,可以把数字设的大一点。[王清培版权所有,转载请给出署名]

在SynchronizationAttribute对象里面有几个枚举值,是用来确定是否共享一个同步域的,有兴趣的可以自己尝试,我就不在这里多讲了。

总结:同步域和上下文对象是线程自动同步的好方法,但是他锁定的目标太大,难免导致系统的吞吐量下降,所以下面几篇文章我们将会学习怎么使用手动同步来实现更灵活的同步(Monitor、WaitHandler等),从很小的粒度进行锁定。






 本文转自 王清培 51CTO博客,原文链接:http://blog.51cto.com/wangqingpei557/652057,如需转载请自行联系原作者


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/257025.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

调用图片按钮的img图片

今天是我学前端的第12天。早上起床后活动筋骨时看了《JS的基本属性操作》&#xff0c;作业是模拟手机发送短信。文字都能传输到<div>上&#xff0c;就是图片不知道怎么传。折腾了好久才弄清楚&#xff0c;多亏了某群的小伙伴们。 这一节课&#xff0c;我学会了如何调用图…

python数据结构_(列表)大O性能_学习笔记(2)

1.列表 1&#xff09;一般列表操作命令的复杂度&#xff08;准确来说是函数的复杂度&#xff09; 2&#xff09;时间计算&#xff08;timeit模块和Timer对象&#xff09; 要捕获我们的每个函数执行所需的时间&#xff0c;我们将使用 Python 的 timeit 模块。timeit 模块旨在 …

找到你的位置(JS在页面中的位置)最常用的方式是在页面中head部分放置script元素,浏览器解析head部分就会执行这个代码,然后才解析页面的其余部分...

找到你的位置&#xff08;JS在页面中的位置&#xff09; 我们可以将JavaScript代码放在html文件中任何位置&#xff0c;但是我们一般放在网页的head或者body部分。放在<head>部分 最常用的方式是在页面中head部分放置<script>元素&#xff0c;浏览器解析head部分就…

3.cocos2dx它Menu,由menu为了实现场景切换

&#xfeff;&#xfeff;1 头文件 TMenu.h #ifndef __TMENU_H__ #define __TMENU_H__ #include "cocos2d.h" USING_NS_CC; class TMenu :public CCLayer { public: static CCScene * scene(); CREATE_FUNC(TMenu); bool init(); CCMenu * menu; void menuCallback(C…

人工智能数学基础知识

方差的概念与计算公式&#xff0c;例1 两人的5次测验成绩如下&#xff1a;X&#xff1a; 50&#xff0c;100&#xff0c;100&#xff0c;60&#xff0c;50 E(X)72&#xff1b;Y&#xff1a; 73&#xff0c; 70&#xff0c; 75&#xff0c;72&#xff0c;70 E(Y)72。平均成绩相同…

认真分析mmap:是什么 为什么 怎么用

mmap基础概念 mmap是一种内存映射文件的方法&#xff0c;即将一个文件或者其它对象映射到进程的地址空间&#xff0c;实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。实现这样的映射关系后&#xff0c;进程就可以采用指针的方式读写操作这一段内存&#xff…

数据库子查询

子查询&#xff0c;又叫做嵌套查询。 将一个查询语句做为一个结果集供其他SQL语句使用&#xff0c;就像使用普通的表一样&#xff0c;被当作结果集的查询语句被称为子查询。 子查询有两种类型&#xff1a; 一种是只返回一个单值的子查询&#xff0c;这时它可以用在一个单值可以…

配置vim在源代码中自动添加作者信息

每个程序员都有自己心爱的代码编辑和查看工具&#xff0c;相信不少Linux下的程序员都喜欢用Vim&#xff0c;尽管Vim没有SourceInsight这种依托于桌面环境的编辑器看起来那样强大&#xff0c;但是Vim的高效、简洁以及强大的可配置性都让它吸引了无数忠实的fans。 很多编辑器都支…

Ubuntu系统盘制作

1、首先打开UltraISO软件&#xff0c;尽量下载最新版的&#xff0c;小编曾用某个旧版的UltraISO&#xff0c;制作的安装盘&#xff0c;不能不能识别磁盘&#xff0c;安装失败! 2、点击工具栏中的第二个打开镜像文件工具&#xff0c;如图红色方框标志按钮&#xff0c;然后在打开…

RH131 网络配置

ip addr show 查看当前网络地址 ip link show 查看网络链接状态 ip -s link show 查看网卡统计信息 ip addr add 192.168.0.154 添加ip地址 ip link dev eth0 down 禁用ip地址 网卡的配置文件/etc/sysconfig/network-scripts/ifcfg-ethx 自动专用地址&#xff1a;169.254.*.* …

学习笔记02:直播串讲02

1.基于模型的学习 根据以往的学习经验&#xff0c;建立起输入输出的模型&#xff0c;然后预测输入&#xff0c;并且将输入带入到模型中&#xff0c;进而预测出输出的结果&#xff0c;这种学习称为基于模型的学习 2.机器学习的过程 1&#xff09;数据收集&#xff1a;通过爬虫、…

Dojo仪表板

Dojo它提供了一个良好的仪表板显示器&#xff0c;的影响&#xff0c;如以下&#xff1a; <!DOCTYPE html> <html> <head><title>Dojo仪表盘</title><meta charset"utf-8"><script src"http://192.168.240.186/arcgis_js…

Exchange2013恢复已删除用户邮箱

上一篇文章我们讲到了如何恢复已禁用的邮箱。但是在微软的Exchange中&#xff0c;禁用邮箱和删除邮箱毕竟是两个截然不同的概念&#xff0c;这篇文章我们就来看看如何恢复已删除的邮箱。 1.依然是新建用户“张三”&#xff0c;然后给其发一封邮件&#xff0c;作为后续邮箱数据恢…

调用异步服务时的超时处理

主线程调用异步服务后&#xff0c;通过设定主线程的等待时间来进行超时处理。Demo如下&#xff1a;AsyncTask.cs 1 using System;2 using System.Threading.Tasks;3 using MyCSharp.ExternalService;4 5 namespace MyCSharp.Grammas6 {7 public class AsyncTask8 {9 …

学习笔记(24):Python网络编程并发编程-进程与线程的区别

立即学习:https://edu.csdn.net/course/play/24458/296438?utm_sourceblogtoedu 线程与进程的区别&#xff1a; 1.消耗区别&#xff1a;进程>线程 1&#xff09;进程运行结果 #进程运行 from multiprocessing import Process def task(name):print("我是%s"%na…

Codeforces Beta Round #1

A /*************************************************************************> File Name: A.cpp> Author: opas_chenxin> Mail: 1017370773qq.com > Created Time: 2016年05月06日 星期五 02时22分23秒 ************************************************…

进程控制块PCB结构体 task_struct 描述

进程控制块&#xff0c;英文名&#xff08;Processing Control Block&#xff09;&#xff0c;简称 PCB 。 进程控制块是系统为了管理进程设置的一个专门的数据结构&#xff0c;主要表示进程状态。 每一个进程都对应一个PCB来维护进程相关的信息&#xff1b; 在Linux中&#xf…

学习笔记(25):Python网络编程并发编程-Thread其他属性和守护线程

立即学习:https://edu.csdn.net/course/play/24458/296440?utm_sourceblogtoedu 1.Thread其他的属性 CurrentThread().getName():获得当前线程的名字 t.is_Alive:判断线程是否还在运行 t.join():等待线程运行结束再执行join后面的代码 t.setName("name"):为线程…

学习笔记(26):Python网络编程并发编程-GIL与自定义互斥锁的区别

立即学习:https://edu.csdn.net/course/play/24458/296443?utm_sourceblogtoedu 1.GIL的基本概念 答&#xff1a;GIL本质上就是一把锁&#xff0c;只是他是一把在python解释器上的锁 2.GIL与互斥锁的区别 答&#xff1a; 1&#xff09;GIL保护的是在python解释器上的参数&a…