动态和静态方法的区别:
动态方法:使用时在内存中实例化该方法,用完释放掉。因为有实例化和释放的过程,所以耗CPU资源
静态方法:创建完内存至一直存在,直接调用即可。因为内存中独占一部分内存,所以耗内存资源。
常用的方法静态比较好。
(问1,我这个理解对吗?)
IIS多线程执行会引发并发访问共享数据(数据库,静态字段,静态方法),导致出现脏读等现象。
(问2,我这个理解对吗?)
为此我们用锁机制来解决该问题,
如:数据库的事务ACID属性,还有.net 里可以用static object ob = new object(); lock (ob)方法加锁。
(问3,我这个理解对吗?)
--------------------------------------
如果两个用户同时读写同一个静态方法,很可能脏读现象,因为静态方法是在内存中唯一的。
(问4,我这个理解对吗?)。
如果两个用户同时读写同一个动态方法,不可能出现脏读现象,因为调用动态方法时在内存中实例化(拷贝一份)独立的方法。
(问5,我这个理解对吗?)
如用“static object ob = new object(); lock (ob){}”方式加锁,修饰符必须是静态。
如果用“static object ob = new object(); lock (ob){}”方式加锁动态/静态方法(SqlHelper),在数据库中可以不用事务锁(ACID)。
(问6,我这理解对吗?)
注:我语文不太好,语法方面可能有错误。如果有不明白的地方请提出来。谢谢!
问题1:这里准确的是叫实例方法和静态方法。而且你这个概念有点混淆,你前面说的好像是实例对象和静态对象,它们都会实例化,只是实例对象是在你new的时候才实例化,而静态对象是在你使用前就已经准备好了,而且就只有一次。
但这个并不会有所谓的cpu资源和内存资源消耗多少的概念,你实例对象在堆或者栈上就不要内存空间了?静态方法在执行时难道不是cpu运算?
问题2:
你应该先仔细了解下脏读,幻读和不可重复读的概念及区别。
抛开这个用法错误外
会,对于程序而言是线程安全性问题。另:ms的framework中所有的静态方法都为线程安全的方法,因此你可以不用纠结string.equals在并发环境下会出现问题。
问题3:对,但并不一定是static,这里只需要保证并发情况下的临界量为同一对象(不可为值类型,最好不要为字符串)即可问题4:不对,出现线程安全性问题是在某时刻同一对象同时对多线程可见,但并不一定会出问题,比如同时读取同一位置的信息。这个和是不是静态方法无关,线程不安全是数据的不安全。
问题5:同上,比如List<T>中的Add方法,这是个实例方法吧?
var list=new List<string>();
var rd=new Random();
var td1=new Thread(()=>list.Add(rd.Next().ToString()));
var td2=new Thread(()=>list.Add(rd.Next().ToString()));
td1.Start();
td2.Start();
这种代码有一定几率抛出异常,而引发异常的原因是list扩容时的线程不安全导致的。
问题6:不对,是不是static上面已经说了,而且就算是你lock了也不能保证数据不出现问题,线上一般情况下都是多进程同时提供服务,你这种lock是不跨进程的,这里所需要做的是在数据库层面上做保证。这里你可以看下有关数据库事务与锁的文章。
谢谢您!
脑洞大开啊,我自以为并发方面理解的很好了,发现方向都错了。
还好今天把疑问拿出来问问大家。
谢谢!
基础不好的问题就是这个.想得多了反而不好.因为基本方向都是错的.
方法不方法.静态不静态都和并发处理没关系.
并发问题叫做:资源竞争.方法函数和并发没有任何关系.因为他们是使用资源的.他们本身不是资源.
建议你百度下令牌环网.看下古人是怎么设计网络结构.并且在网络中怎么处理并发.
令牌环网的思想也是现在的资源竞争解决方案的基础.
谢谢您的建议!
还是多看资料学习基础知识最重要,不然又走错方向白费时间。
谢谢!