C#线程安全使用(三)

C#线程安全使用(三),第1张

概述在讲CancellationTokenSource之前我决定先讲一下lock和Interlocked,如果能很好的理解这两个,再去理解CancellationTokenSource就会方便很多,由于我

在讲CancellationTokenSource之前我决定先讲一下lock和Interlocked,如果能很好的理解这两个,再去理解CancellationTokenSource就会方便很多,由于我也是后起使用多线程,使用的时候就是直接运用FramWork4的东西,这样导致了很多东西学起来很吃力,当回顾了以前的知识点后,发现新出的东西如此好理解。

先看一下Lock的使用,下面是一个例子。

<span >namespace<span > LockConsole
{
<span >class
<span > Program
{
<span >static
<span >object
lockint = <span >0
<span >;
<span >static
<span >voID
<span > Main()
{
Task[] tList
=<span >new Task[<span >10<span >];

        Thread[] threads </span>= <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;new</span> Thread[<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800080;"&gt;10</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;];        </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;for</span> (<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;int</span> i = <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800080;"&gt;0</span>; i < <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800080;"&gt;10</span>; i++<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;)        {         </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;var</span> action =   <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;new</span> Action<<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;object</span>><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;(Withdraw);         Task t </span>= <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;new</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; Task(action,i);         t<a href="https://m.jb51.cc/tag/List/" target="_blank" >List</a>[i] </span>=<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; t;            </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"&gt;//</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"&gt;Thread t = new Thread(new ThreadStart(acc.DoTransactions));            </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"&gt;//</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"&gt;threads[i] = t;</span>

<span > }
<span >for (<span >int i = <span >0; i < <span >10; i++<span >)
{
tList[i].Start();

            </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"&gt;//</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"&gt;threads[i].Start();</span>

<span > }
Console.Read();
}

    </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;static</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;vo<a href="https://m.jb51.cc/tag/ID/" target="_blank" >ID</a></span> Withdraw(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;object</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; i)    {        </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;int</span> amount = <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;int</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;.Parse(i.ToString());        </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;int</span>  balance = <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800080;"&gt;1000</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;;        </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;lock</span> (lockint)<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"&gt;//</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"&gt;<a href="https://www.jb51.cc/tag/shanchu/" target="_blank" >删除</a>lock就会造成 线程混乱</span>

<span > {
<span >if (balance >=<span > amount)
{
Console.Writeline(<span >"<span >当前线程{0},当前状态{1}<span >",Thread.CurrentThread.GetHashCode(),Thread.CurrentThread.ThreadState + <span >"<span >Balance before Withdrawal : <span >" +<span > balance);
Console.Writeline(<span >"<span >当前线程{0},Thread.CurrentThread.ThreadState + <span >"<span >Amount to Withdraw : -<span >" +<span > amount);
balance = balance -<span > amount;
Console.Writeline(<span >"<span >当前线程{0},Thread.CurrentThread.ThreadState + <span >"<span >Balance after Withdrawal : <span >" +<span > balance);

            }        }    }}

}

输出结果如下,他的线程都是一个接一个的,线程11后是线程12,然后是13,14,11等。每个线程都是等到执行完了下一个才执行。

 

在看一下没有Lock的结果,如下图,线程是混乱的,12线程的函数没执行完13就开始了。

有了上面的例子,Lock就很好理解了,他是为了保障资源同一时间只被一个线程使用,虽然该例子中没有使用Lock的资源,但线程还是一个接一个的执行,因为使用了lock线程就会一个接一个执行。

接下来看一下interLock,这是一个MSDN的例子,我觉得不错,他的意思是,把usingResource作为一个锁,当多线程开始运行,函数UseResource()需要判断usingResource的值,当usingResource等于0的时候,当前线程不运行,否则运行,当本线程运行时,要修改usingResource的值为1,这样确保其他线程不运行,即同一时间只运行一个线程。

如果这样需求用到开发中,会出现一个问题,那就是当一个线程改变usingResource的值的一瞬间,别的线程读取了usingResource的值,那这个线程也被运行了。

这时就需要InterLock了。代码如下。

<span >namespace<span > MyInterlockedExchangeExampleClass
{
<span >class
<span > MyInterlockedExchangeExampleClass
{
<span >//
<span >0 for false,1 for true.

<span >private
<span >static
<span >int
usingResource = <span >0
<span >;

    </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;private</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;const</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;int</span> numThreadI<a href="https://www.jb51.cc/tag/tera/" target="_blank" >tera</a>tions = <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800080;"&gt;5</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;;    </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;private</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;const</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;int</span> numThreads = <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800080;"&gt;10</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;;    </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;static</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;vo<a href="https://m.jb51.cc/tag/ID/" target="_blank" >ID</a></span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; Main()    {        Thread myThread;        Random rnd </span>= <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;new</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; Random();        </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;for</span> (<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;int</span> i = <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800080;"&gt;0</span>; i < numThreads; i++<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;)        {            myThread </span>= <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;new</span> Thread(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;new</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; ThreadStart(MyThreadProc));            myThread.<a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a> </span>= String.Format(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;Thread{0}</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;"</span>,i + <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800080;"&gt;1</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;);            </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"&gt;//</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"&gt;Wait a random amount of time before starting next thread.</span>            Thread.Sleep(rnd.Next(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800080;"&gt;0</span>,<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800080;"&gt;1000</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;));            myThread.Start();        }    }    </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;private</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;static</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;vo<a href="https://m.jb51.cc/tag/ID/" target="_blank" >ID</a></span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; MyThreadProc()    {        </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;for</span> (<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;int</span> i = <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800080;"&gt;0</span>; i < numThreadI<a href="https://www.jb51.cc/tag/tera/" target="_blank" >tera</a>tions; i++<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;)        {            UseResource();            </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"&gt;//</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"&gt;Wait 1 second before next attempt.</span>            Thread.Sleep(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800080;"&gt;1000</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;);        }    }    </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"&gt;//</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"&gt;A simple method that den<a href="https://m.jb51.cc/tag/IE/" target="_blank" >IE</a>s reentrancy.</span>    <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;static</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;bo<a href="https://m.jb51.cc/tag/ol/" target="_blank" >ol</a></span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt; UseResource()    {        </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"&gt;//</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"&gt;0 indicates that the method is not in use.        </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"&gt;//</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"&gt;原始值是0,判断是时候<a href="https://m.jb51.cc/tag/shiyong/" target="_blank" >使用</a>原始值,但判断后值为1,<a href="https://m.jb51.cc/tag/jinxing/" target="_blank" >进行</a>了<a href="https://m.jb51.cc/tag/shezhi/" target="_blank" >设置</a></span>        <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;if</span> (<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800080;"&gt;0</span> == Interlocked.Exchange(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;ref</span> usingResource,<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800080;"&gt;1</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;))        {            Cons<a href="https://m.jb51.cc/tag/ol/" target="_blank" >ol</a>e.Write<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne(</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;{0} acquired the lock</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;,Thread.CurrentThread.<a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a>);            </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"&gt;//</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"&gt;Code to access a resource that is not thread safe wo<a href="https://m.jb51.cc/tag/ul/" target="_blank" >ul</a>d go here.            </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"&gt;//</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"&gt;Sim<a href="https://m.jb51.cc/tag/ul/" target="_blank" >ul</a>ate some work</span>            Thread.Sleep(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800080;"&gt;500</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;);            Cons<a href="https://m.jb51.cc/tag/ol/" target="_blank" >ol</a>e.Write<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne(</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;{0} exiting lock</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;,Thread.CurrentThread.<a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a>);            </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"&gt;//</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"&gt;Release the lock</span>            Interlocked.Exchange(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;ref</span> usingResource,<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800080;"&gt;0</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;);            </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;return</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;true</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;;        }        </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;else</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;        {            Cons<a href="https://m.jb51.cc/tag/ol/" target="_blank" >ol</a>e.Write<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ne(</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;   {0} was den<a href="https://m.jb51.cc/tag/IE/" target="_blank" >IE</a>d the lock</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000;"&gt;"</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;,Thread.CurrentThread.<a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a>);            </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;return</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;"&gt;false</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"&gt;;        }    }}

}

理解了lock和interlock后下一章讲解CancellationTokenSource。

总结

以上是内存溢出为你收集整理的C#线程安全使用(三)全部内容,希望文章能够帮你解决C#线程安全使用(三)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1264261.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存