选择恒定的原子值类型数据
-
如果要对原子值和互斥锁进行二选一,最重要的三个决策条件应该是什么?
2021-02-23 23:26:06如果要对原子值和互斥锁进行二选一,你认为最重要的三个决策条件应该是什么?</p> -
7.选择恒定的原子值类型数据
2012-10-22 16:48:00选择恒定的原子值类型数据 转载于:https://www.cnblogs.com/movemoon/archive/2012/10/22/2734172.html转载于:https://www.cnblogs.com/movemoon/archive/2012/10/22/2734172.html
-
Effective C# 原则7: 选择恒定的原子值类型数据
2009-05-04 09:09:00Effective C# 原则7: 选择恒定的原子值类型数据恒定类型(immutable types)其实很简单,就是一但它们被创建,它们(的值)就是固定的。如果你验证一些准备用于创建一个对象的参数,你知道它在验证状态从前面的观点上看...Effective C# 原则7: 选择恒定的原子值类型数据
恒定类型(immutable types)其实很简单,就是一但它们被创建,它们(的值)就是固定的。如果你验证一些准备用于创建一个对象的参数,你知道它在验证状态从前面的观点上看。你不能修改一个对象的内部状态使之成为无效的。在一个对象被创建后,你必须自己小心翼翼的保护对象,否则你不得不做错误验证来禁止改变任何状态。恒定类型天生就具有线程完全性的特点:多访问者可同时访问相同的内容。如果内部状态不能修改,那么就不能给不同的线程提供查看不一致的数据视图的机会。恒定类型可以从你的类上安全的暴露出来。调用者不能修改对象的内部状态。恒定类型可以很好的在基于哈希代码的集合上工作。以Object.GetHashCode()方法返回的值,对同一个实例是必须相同的(参见原则10),而这正是恒定类型总能成功的地方。
并不是所有的类型都能成为恒定类型的。如果它可以,你需要克隆一个对象用于修改任何程序的状态了。这就是为什么同时推荐使用恒定类型和原子类型数据了。把你的对象分解为自然的单一实体结构。一个Address类型就是的,它就是一个简单的事,由多个相关的字段组成。改变其中一个字段就很可能意味着修改了其它字段。一个客户类型不是一个原子类型,一个客户类型可能包含很多小的信息块:地址,名字,一个或者多个电话号码。任何一个互不关联的信息块都可以改变。一个客户可能会在不搬家的情况下改变电话号码。而另一个客户可能在搬了家的情况下保留原来的电话号码。还有可能,一个客户改变了他(她)的名字,而没有搬家也没有改电话号码。一个客户类型就不是原子类型;它是由多个不同的恒定的组成部份构成的:地址,名字,以及一个成对出现的电话号码集合。原子类型是单一实体:你很自然的用原子类型来取代实体内容。这一例外会改变它其中的一个组成字段。
下面就是一个典型的可变地址类的实现:
// Mutable Address structure.
public struct Address
{
private string _line1;
private string _line2;
private string _city;
private string _state;
private int _zipCode;// Rely on the default system-generated
// constructor.public string Line1
{
get { return _line1; }
set { _line1 = value; }
}
public string Line2
{
get { return _line2; }
set { _line2 = value; }
}
public string City
{
get { return _city; }
set { _city= value; }
}
public string State
{
get { return _state; }
set
{
ValidateState(value);
_state = value;
}
}
public int ZipCode
{
get { return _zipCode; }
set
{
ValidateZip( value );
_zipCode = value;
}
}
// other details omitted.
}// Example usage:
Address a1 = new Address( );
a1.Line1 = "111 S. Main";
a1.City = "Anytown";
a1.State = "IL";
a1.ZipCode = 61111 ;
// Modify:
a1.City = "Ann Arbor"; // Zip, State invalid now.
a1.ZipCode = 48103; // State still invalid now.
a1.State = "MI"; // Now fine.内部状态的改变意味着它很可能违反了对象的不变性,至少是临时的。当你改变了City这个字段后,你就使a1处于无效状态。城市的改变使得它与洲字段及以区码字段不再匹配。代码的有害性看上去还不足以致命,但这对于多线程程序来说只是一小部份。在城市变化以后,洲变化以前的任何内容转变,都会潜在的使另一个线程看到一份矛盾的数据视图。
Okay,所以你不准备去写多线程程序。你仍然处于困境当中。想象这样的问题,区代码是无效的,并且设置抛出了一个异常。你只是完成了一些你想做的事,可你却使系统处于一个无效的状态当中。为了修正这个问题,你须要在地址类里面添加一个相当大的内部验证码。这个验证码应该须要相当大的空间,并且很复杂。为了完全实现期望的安全性,当你修改多个字段时,你须要在你的代码块周围创建一个被动的数据COPY。线程安全性可能要求添加一个明确的线程同步用于检测每一个属性访问器,包括set和get。总而言之,这将是一个意义重大的行动--并且这很可能在你添加新功能时被过分的扩展。
取而代之,把address结构做为一个恒定类型。开始把所有的字段都改成只读的吧:
public struct Address
{
private readonly string _line1;
private readonly string _line2;
private readonly string _city;
private readonly string _state;
private readonly int _zipCode;// remaining details elided
}你还要移除所有的属性设置功能:
public struct Address
{
// ...
public string Line1
{
get { return _line1; }
}
public string Line2
{
get { return _line2; }
}
public string City
{
get { return _city; }
}
public string State
{
get { return _state; }
}
public int ZipCode
{
get { return _zipCode; }
}
}现在,你就拥有了一个恒定类型。为了让它有效的工作,你必须添加一个构造函数来完全初始化address结构。这个address结构只须要额外的添加一个构造函数,来验证每一个字段。一个拷贝构造函数不是必须的,因为赋值运算符还算高效。记住,默认的构造函数仍然是可访问的。这是一个默认所有字符串为null,ZIP代码为0的地址结构:
public struct Address
{
private readonly string _line1;
private readonly string _line2;
private readonly string _city;
private readonly string _state;
private readonly int _zipCode;public Address( string line1,
string line2,
string city,
string state,
int zipCode)
{
_line1 = line1;
_line2 = line2;
_city = city;
_state = state;
_zipCode = zipCode;
ValidateState( state );
ValidateZip( zipCode );
}// etc.
}在使用这个恒定数据类型时,要求直接用不同的调用来一顺的修改它的状态。你更宁愿创建一个新的对象而不是去修改某个实例:
// Create an address:
Address a1 = new Address( "111 S. Main",
"", "Anytown", "IL", 61111 );// To change, re-initialize:
a1 = new Address( a1.Line1,
a1.Line2, "Ann Arbor", "MI", 48103 );a1的值是两者之一:它的原始位置Anytown,或者是后来更新后的位置Ann Arbor。你再不用像前面的例子那样,为了修改已经存在的地址而使对象产生临时无效状态。这里只有一些在构造函数执行时才存在的临时状态,而在构造函数外是无法访问内部状态的。很快,一个新的地址对象很快就产生了,它的值就一直固定了。这正是期望的安全性:a1要么是默认的原始值,要么是新的值。如果在构造对象时发生了异常,那么a1保持原来的默认值不变。
(译注:为什么在构造时发生异常不会影响a1的值呢?因为只要构造函数没有正确返回,a1都只保持原来的值。因为是那是一个赋值语句。这也就是为什么要用构造函数来实现对象更新,而不是另外添加一个函数来更新对象,因为就算用一个函数来更新对象,也有可能更新到一半时,发生异常,也会使得对象处于不正确的状态当中。大家可以参考一下.Net里的日期时间结构,它就是一个典型的恒定常量例子。它没有提供任何的对单独年,月,日或者星期进行修改的方法。因为单独修改其中一个,可能导致整个日期处于不正确的状态:例如你把日期单独的修改为31号,但很可能那个月没有31号,而且星期也可能不同。它同样也是没提供任何方法来同时设置所以参数,读了条原则后就明白为什么了吧。参考一下DateTime结构,可以更好的理解为什么要使用恒定类型。注:有些书把immutable type译为不变类型。)
为了创建一个恒定类型,你须要确保你的用户没有任何机会来修改内部状态。值类型不支持派生类,所以你不必定义担心派生类来修改它的内部状态。但你须要注意任何在恒定类型内的可变的引用类型字段。当你为这些类型实现了构造函数后,你须要被动的把可变的引用类型COPY一遍(译注:被动COPY,defensive copy,文中应该是指为了保护数据,在数据赋值时不得不进行的一个COPY,所以被认为是“防守”拷贝,我这里译为:被动拷贝,表示拷贝不是自发的,而是不得以而为之的)。
所有这些例子,都是假设Phone是一个恒定的值类型,因为我们只涉及到值类型的恒定性:// Almost immutable: there are holes that would
// allow state changes.
public struct PhoneList
{
private readonly Phone[] _phones;public PhoneList( Phone[] ph )
{
_phones = ph;
}public IEnumerator Phones
{
get
{
return _phones.GetEnumerator();
}
}
}Phone[] phones = new Phone[10];
// initialize phones
PhoneList pl = new PhoneList( phones );// Modify the phone list:
// also modifies the internals of the (supposedly)
// immutable object.
phones[5] = Phone.GeneratePhoneNumber( );这个数组是一个引用类型。PhoneList内部引用的数组,引用了分配在对象外的数组存储空间上。开发人员可以通过另一个引用到这个存储空间上的对象来修改你的恒定结构。为了避免这种可能,你须要对这个数组做一个被动拷贝。前面的例子显示了可变集合的弊端。如果电话类型是一个可变的引用类型,它还会有更多危害存在的可能。客户可以修改它在集合里的值,即使这个集合是保护,不让任何人修改。这个被动的拷贝应该在每个构造函数里被实现,而不管你的恒定类型里是否存在引用对象:
// Immutable: A copy is made at construction.
public struct PhoneList
{
private readonly Phone[] _phones;public PhoneList( Phone[] ph )
{
_phones = new Phone[ ph.Length ];
// Copies values because Phone is a value type.
ph.CopyTo( _phones, 0 );
}public IEnumerator Phones
{
get
{
return _phones.GetEnumerator();
}
}
}Phone[] phones = new Phone[10];
// initialize phones
PhoneList pl = new PhoneList( phones );// Modify the phone list:
// Does not modify the copy in pl.
phones[5] = Phone.GeneratePhoneNumber( );当你返回一个可变类型的引用时,也应该遵守这一原则。如果你添加了一个属性用于从PhoneList结构中取得整个数组的链表,这个访问器也必须实现一个被动拷贝。详情参见原则23。
这个复杂的类型表明了三个策略,这是你在初始化你的恒定对象时应该使用的。这个Address结构定义了一个构造函数,让你的客户可以初始化一个地址,定义合理的构造函数通常是最容易达到的。
你同样可以创建一个工厂方法来实现一个结构。工厂使得创建一个通用的值型数据变得更容易。.Net框架的Color类型就是遵从这一策略来初始化系统颜色的。这个静态的方法Color.FromKnownColor()和Color.FromName()从当前显示的颜色中拷贝一个给定的系统颜色,返回给用户。
第三,你可以为那些需要多步操作才能完成构造函数的恒定类型添加一个伴随类。.Net框架里的字符串类就遵从这一策略,它利用了伴随类System.Text.StringBuilter。你是使用StringBuliter类经过多步操作来创建一个字符串。在完成了所有必须步骤生成一个字符串类后,你从StringBuilter取得了一个恒定的字符串。
(译注:.net里的string是一但初始化,就不能再修改,对它的任何改动都会生成新的字符串。因此多次操作一个string会产生较多的垃圾内存碎片,你可以用StringBuliter来平衡这个问题。)恒定类型是更简单,更容易维护的。不要盲目的为你的每一个对象的属性创建get和set访问器。你对这些类型的第一选择是把这些数存储为恒定类型,原子类型。从这些实体中,你可以可以容易的创建更多复杂的结构。
-
转:《Effective C#》Item 7:推荐使用不可改变的原子值类型
2007-09-30 13:27:00转:http://dev.csdn.net/author/Knight94/5582b364fc744be09bca2dca36786322.html《Effective C#》Item 7:推荐使用不可改变的原子值类型 首先来解释一下标题,原标题为《Prefer Immutable Atomic Value Type》,...转:http://dev.csdn.net/author/Knight94/5582b364fc744be09bca2dca36786322.html
《Effective C#》Item 7:推荐使用不可改变的原子值类型首先来解释一下标题,原标题为《Prefer Immutable Atomic Value Type》,因此对于标题的理解要分成三部分,第一部分为不可改变,第二部分为原子,最后一个部分为值类型CSDN也经常提到,例如保证操作的原子性之类的语句,那么一个原子类型,其的子成员为不可分割的一部分,不能单独被操作。。最后一部分,我不多说了,限制此章适用的范围。对于什么是不可改变类型,这里的意思是指此类型的变量一旦产生其成员就不能发生变化。至于原子类型,我以前在听了标题解释,难免有些人会问,为什么要加上这样的限制,或者说这样做的好处是什么。为了解开这个疑团,我用一个例子来说明,去定义一个电话号码的值类型,一般形式如下:public struct Phone{private string strCountry_Code;private string strCity_Code;private string strPhone_Number;public string Country_Code{get{ return strCountry_Code; }set{ strCountry_Code = value;}}public string City_Code{get{ return strCity_Code; }set{ strCity_Code = value;}}public string Phone_Number{get{ return strPhone_Number; }set{ strPhone_Number = value;}}// Constructorpublic Phone( string sCountry_Code, string sCity_Code, string sPhone_Number ){strCountry_Code = sCountry_Code;strCity_Code = sCity_Code;strPhone_Number = sPhone_Number;}}这样去初始化一个Phone类型变量的话,同时也可以做类似如下的相关操作。Phone myPhone = new Phone( "086", "010", "66666666" );myPhone.City_Code = "021";myPhone.Phone_Number = "777777777";大多数人觉得如上的代码没有什么问题,不过稍微明眼的人看了如上的代码,就会立刻觉得有潜在的危险。作为一个Phone类型变量来说,国家区号,城市区号,以及电话号码来说是一个整体。因此动态修改其中的某一个值,会造成其他两个无效。也就是说如上的代码直接修改City_Code的时候,对于myPhone来说其他两个变量Country_Code以及Phone_Number来说,此时是无效的。不过这种错误在单线程中不是很明显,但是在多线程中是致命的,而且很难查出来。Lock语句或者互斥标识来避免。这样是可以避免,但是试问一下,类型是你创建的,你怎么要求别人在使用你这个类型的时候做过多的操纵呢,为什么你不在创建此类型的时候就直接把这条路堵死。如果明白了这一点,就理解了这篇文章推荐的目的,即与其后期增加代码弥补,不如在前期就编写正确的代码。有人可能会说了,在修改的时候加上知道这样做的原因,接下来就是如何去实现。不过在实现之前,要区分什么样的数据类型可以定义成不可变的原子类型。也就是说,你如何区分一个类型是一个整体,而且每个分支不能独立于整体而存在。例如对于联系方式这个类型来说,它包括电话号码、住址等等。它可以看为一个整体,但是分支可以脱离这个整体而存在,因此它不是一个原子类型。对于如何具体区分,很难有一个统一的方法,毕竟适应的环境不同,操作以及实现也不同。不过对于原子类型,有一个唯一判断方式,就是每个分支能否独立于整体而被操作,这个的是与否决定是否为原子类型。那么如何去定义一个不可变的原子值类型呢,大致要对原有的类型做两个处理,一个就是把所有成员加上readonly标示,即只能在构造函数中被修改;另一个就是删除属性set部分。对于Phone这个类型来说,经过处理后,正确的形式如下:public struct Phone{private readonly string strCountry_Code;private readonly string strCity_Code;private readonly string strPhone_Number;public string Country_Code{get{ return strCountry_Code; }}public string City_Code{get{ return strCity_Code; }}public string Phone_Number{get{ return strPhone_Number; }}// Constructorpublic Phone( string sCountry_Code, string sCity_Code, string sPhone_Number ){strCountry_Code = sCountry_Code;strCity_Code = sCity_Code;strPhone_Number = sPhone_Number;}}这样对于一个Phone类型变量,只能通过new来创建(也就是说在输入三个有效的数据后,一个Phone类型变量才能产生)。在此有人会问,除了new是否还有其他方法来进行修改。这是没有任何问题的,首先你只要理解了原子类型的意义,保证分支不会单独被修改即可,因此可以实现类似于“Phone.Parse”或者“Phone.From”之类的函数来形成一个新的Phone变量。在实现不可变的原子值类型的时候,要防止类型中包括引用类型分支的时候,在进行成员赋值的时候,防止浅copy,这方面我就不多说了,参看我以前写的文章就可以明白(这里的目的也就是一点,防止局部破坏原子类型的分支)。 -
[转载]《Effective C#》Item 7:推荐使用不可改变的原子值类型
2019-07-02 16:15:07《Effective C#》Item 7:推荐使用不可改变的原子值类型《Effective C#》Item 7:推荐使用不可改变的原子值类型 首先来解释一下标题,原标题为《Prefer Immutable Atomi...《Effective C#》Item 7:推荐使用不可改变的原子值类型
《Effective C#》Item 7:推荐使用不可改变的原子值类型首先来解释一下标题,原标题为《Prefer Immutable Atomic Value Type》,因此对于标题的理解要分成三部分,第一部分为不可改变,第二部分为原子,最后一个部分为值类型。最后一部分,我不多说了,限制此章适用的范围。对于什么是不可改变类型,这里的意思是指此类型的变量一旦产生其成员就不能发生变化。至于原子类型,我以前在CSDN也经常提到,例如保证操作的原子性之类的语句,那么一个原子类型,其的子成员为不可分割的一部分,不能单独被操作。
听了标题解释,难免有些人会问,为什么要加上这样的限制,或者说这样做的好处是什么。为了解开这个疑团,我用一个例子来说明,去定义一个电话号码的值类型,一般形式如下:
public struct Phone
{
private string strCountry_Code;
private string strCity_Code;
private string strPhone_Number;
public string Country_Code
{
get{ return strCountry_Code; }
set{ strCountry_Code = value;}
}
public string City_Code
{
get{ return strCity_Code; }
set{ strCity_Code = value;}
}
public string Phone_Number
{
get{ return strPhone_Number; }
set{ strPhone_Number = value;}
}
// Constructor
public Phone( string sCountry_Code, string sCity_Code, string sPhone_Number )
{
strCountry_Code = sCountry_Code;
strCity_Code = sCity_Code;
strPhone_Number = sPhone_Number;
}
}
这样去初始化一个Phone类型变量的话,同时也可以做类似如下的相关操作。
Phone myPhone = new Phone( "086", "010", "66666666" );
myPhone.City_Code = "021";
myPhone.Phone_Number = "777777777";
大多数人觉得如上的代码没有什么问题,不过稍微明眼的人看了如上的代码,就会立刻觉得有潜在的危险。作为一个Phone类型变量来说,国家区号,城市区号,以及电话号码来说是一个整体。因此动态修改其中的某一个值,会造成其他两个无效。也就是说如上的代码直接修改City_Code的时候,对于myPhone来说其他两个变量Country_Code以及Phone_Number来说,此时是无效的。不过这种错误在单线程中不是很明显,但是在多线程中是致命的,而且很难查出来。有人可能会说了,在修改的时候加上Lock语句或者互斥标识来避免。这样是可以避免,但是试问一下,类型是你创建的,你怎么要求别人在使用你这个类型的时候做过多的操纵呢,为什么你不在创建此类型的时候就直接把这条路堵死。如果明白了这一点,就理解了这篇文章推荐的目的,即与其后期增加代码弥补,不如在前期就编写正确的代码。
知道这样做的原因,接下来就是如何去实现。不过在实现之前,要区分什么样的数据类型可以定义成不可变的原子类型。也就是说,你如何区分一个类型是一个整体,而且每个分支不能独立于整体而存在。例如对于联系方式这个类型来说,它包括电话号码、住址等等。它可以看为一个整体,但是分支可以脱离这个整体而存在,因此它不是一个原子类型。对于如何具体区分,很难有一个统一的方法,毕竟适应的环境不同,操作以及实现也不同。不过对于原子类型,有一个唯一判断方式,就是每个分支能否独立于整体而被操作,这个的是与否决定是否为原子类型。
那么如何去定义一个不可变的原子值类型呢,大致要对原有的类型做两个处理,一个就是把所有成员加上readonly标示,即只能在构造函数中被修改;另一个就是删除属性set部分。对于Phone这个类型来说,经过处理后,正确的形式如下:
public struct Phone
{
private readonly string strCountry_Code;
private readonly string strCity_Code;
private readonly string strPhone_Number;
public string Country_Code
{
get{ return strCountry_Code; }
}
public string City_Code
{
get{ return strCity_Code; }
}
public string Phone_Number
{
get{ return strPhone_Number; }
}
// Constructor
public Phone( string sCountry_Code, string sCity_Code, string sPhone_Number )
{
strCountry_Code = sCountry_Code;
strCity_Code = sCity_Code;
strPhone_Number = sPhone_Number;
}
}
这样对于一个Phone类型变量,只能通过new来创建(也就是说在输入三个有效的数据后,一个Phone类型变量才能产生)。
在此有人会问,除了new是否还有其他方法来进行修改。这是没有任何问题的,首先你只要理解了原子类型的意义,保证分支不会单独被修改即可,因此可以实现类似于“Phone.Parse”或者“Phone.From”之类的函数来形成一个新的Phone变量。
在实现不可变的原子值类型的时候,要防止类型中包括引用类型分支的时候,在进行成员赋值的时候,防止浅copy,这方面我就不多说了,参看我以前写的文章就可以明白(这里的目的也就是一点,防止局部破坏原子类型的分支)。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/374079/viewspace-130539/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/374079/viewspace-130539/
-
《Effective C#》Item 7:推荐使用不可改变的原子值类型
2008-06-25 20:03:00首先来解释一下标题,原标题为《Prefer Immutable Atomic Value Type》,因此对于标题的理解要分成三部分,第一部分为不可改变,第二部分为原子,最后一个部分为值类型。最后一部分,我不多说了,限制此章适用的范围... -
AtomicBoolean 原子布尔值
2019-06-03 18:50:00介绍:在这个Boolean值的变化的时候不允许在之间插入,保持操作的原子性 方法和举例:compareAndSet(boolean expect, boolean update)这个方法主要两个作用 比较AtomicBoolean和expect的值,如果一致,执行... -
原子性获取最大值
2015-11-20 16:45:36原子性获取最大值 void Set(int64_t i) { for(;;) { int64_t v = common::AtomicGet(pValue); if (common::AtomicCompareExchange(pValue, v, max(v,i))) -
MYSQL 原子得到UPDATE变化的值
2013-11-27 11:33:58MYSQL原子得到UPDATE变化的值 -
创建常量、原子性的值类型
2014-01-09 16:04:50通过这篇文章,我主要想向大家说明一个我们平时可能不太会注意到的问题:创建具有常量性和原子性的值类型。 从类型设计谈起 从Class到Struct 假如我们要设计一个存储收信人地址的类型(Type), 我们管这个类型叫 ... -
正点原子示例程序修改默认晶振值
2018-02-24 16:30:00将串口示例程序直接烧在自己的板子上发现不能用,检查引脚配置都正确,查了下晶振发现自己的板子上是12M晶振,而ST官方和原子的示例默认是8M的 在system_stm32f10x.c中有这样一段话: 修改步骤: 1. 在stm32f10... -
08-同步5-原子操作
2020-11-26 09:03:15文章目录一 原子操作理解二 常用原子操作2.1 原子运算:增/减2.2 原子运算:比较与替换2.3 原子读取:载入2.4 原子写入:存储2.5 交换三 原子值 一 原子操作理解 对并发的操作,可以利用Go新提出的管道思想,大多数... -
Golang学习笔记:原子操作
2020-06-02 19:45:51原子值sync/atomic.Value 简介 执行过程中不能被中断的操作。在针对某个值的操作过程中,CPU绝不会再去执行其它针对该值的操作,无论这些其他操作是否是原子操作。 对于不能被取地址的值是无法进行原子操作... -
java 通过地址获取值_Java并发系列:CAS与原子变量
2020-11-25 23:56:07CAS操作包含三个操作数内存值V、预期原值A和新值B,当且仅当预期原值A和内存值V相同时,将内存值V修改为新值B,否则,处理器不做任何操作。// CAS C++示意int compare_and_swap (int* reg, int oldval, int newval) ... -
正点原子 图像处理 二值化处理 电赛 滚球系统单点定位
2019-07-12 10:47:05图像处理 二值化处理 滚球系统单点定位 把程序直接烧录探索者可直接测试 -
java替换map中的值_Java:如何以原子方式替换Map中的所有值?
2021-03-15 03:17:57现在,我需要一种在一次原子操作中替换该映射的所有值的方法。public final class StatefulBean {private final Map state = new ConcurrentSkipListMap<>();public StatefulBean() {//Initial statethis.s... -
redis lock优化(保证redis值、过期时间原子性以及删除锁原子操作)
2020-07-07 11:04:51/** * @author Jiangjunjie * @Date 2020/7/7 * 通过给set NX(一个有锁,其他线程不能再获取锁),PX(设置锁的自动过期时间) 进行保证redis的值以及过期时间的原子性 * 通过给锁设置一个拥有者的标识,即每次在获取锁... -
AtomicLong可以被原子地读取和写入的底层long值的操作
2018-06-06 17:20:00java.util.concurrent.atomic.AtomicLong类提供了可以被原子地读取和写入的底层long值的操作,并且还包含高级原子操作。AtomicLong支持基础long类型变量上的原子操作。 它具有获取和设置方法,如在volatile变量上的... -
原子性与原子操作
2017-10-12 15:27:57原子性:如果把一个事务可看作是一个程序,它要么完整的被执行,要么完全不执行。 原子性达到的目标:就是能使一个程序被完整的执行。 原子操作:不可被中断的一个或一系列的操作。 CAS有3个操作数,内存值V,... -
正点原子STM32F407 DMA+ADC 连续采样24路ADC的值 并且将ADC的值用屏幕显示
2018-10-06 17:25:18资源是基于Stm32F407的代码,可以在正点原子探索者上面非常好的运行,代码的作用是轮询扫描共计24路的ADC接口并且将 得到的ADC的值保存在数组中,最终通过屏幕的方式显示出来(使用开发板的时候很多IO被内置上下拉,... -
AtomicInteger原子的使用
2012-04-07 14:12:17原子值:主要用于缓存中唯一的要求,比如队伍,要分配一个 id,并且该id不保存数据库.每次重启服务器,都从指定的值开始. 尝试使用了AtomicInteger这个类,感觉使用起来很爽,特别适用于高并发访问 public static ... -
CXF原子服务WSDL xs:element中自定义type值
2017-08-12 01:28:31如图显示,我想把type值大小写改了,不影响name值,这个要怎么解决 -
原子变量和原子操作
2017-06-04 19:47:31原子变量和原子操作通常情况下,在Java里面,++i或者–i不是线程安全的,这里面有三个独立的操作:获得变量当前值,为该值+1/-1,然后写回新的值。在没有额外资源可以利用的情况下,只能使用加锁才能保证读-改-写这... -
redis将散裂中某个值自增_Redis的原子自增性
2021-01-12 20:16:30INCR key将key中储存的数字值增一。如果key不存在,那么key的值会先被初始化为0,然后再执行INCR操作。如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。本操作的值限制在 64 位(bit)有... -
原子相干对里德伯原子稳定性的影响
2021-02-11 06:44:09研究了含级联双光子过程的多束缚态激光场诱导原子连续态结构系统中原子的相干捕获,给出了产生相干捕获的条件及暗态的表达式,讨论了原子初态和激光强度对原子相干捕获及粒子布居值在束缚态上分布的影响,揭示了原子...