• C#学习第八弹之线程基础理解


          学过Linux或者Java的应该都知道线程的概念,C#也支持通过多个线程来并行执行任务。任何一个C#的程序会开始于一个单线程(由CLR和OS自动创建的主线程)。

    下面是简单的例子:

     1 using System;
     2 using System.Threading;
     3 
     4 namespace Test
     5 {
     6     class Program
     7     {
     8         static void WriteX()
     9         {
    10             for ( int i = 0; i < 10; i++ )
    11             {
    12                 Console.Write('X');
    13             }
    14         }
    15 
    16         static void WriteY()
    17         {
    18             for ( int i = 0; i < 10; i++ )
    19             {
    20                 Console.Write('Y');
    21             }
    22         }
    23 
    24         static void Main(string[] args)
    25         {
    26             new Thread(WriteX).Start();
    27             WriteY();
    28         }
    29     }
    30 }

    运行结果如下:

    很显然结果不可预料,又一次运行结果如下:

    原因是我们并没有规定两个线程的优先级。

    ThreadPriority属性可以设定它的优先级别,包括:Normal, AboveNormal, BelowNormal, Highest, and Lowest等。

    更改方法:

    thread.Priority = ThreadPriority.Highest;

    可能引起的一个问题就是“线程安全“,请看下面的例子:

     1 using System;
     2 using System.Threading;
     3 
     4 namespace Test
     5 {
     6     class Program
     7     {
     8         static bool flag = false;
     9 
    10         static void go( string str )
    11         {
    12             if (!flag)
    13             {
    14                 flag = true;
    15                 Console.Write(str+"Victory");
    16             }
    17         }
    18 
    19         static void foo()
    20         {
    21             go("foo");
    22         }
    23 
    24         static void bar()
    25         {
    26             go("bar");
    27         }
    28 
    29         static void Main(string[] args)
    30         {
    31             new Thread(foo).Start();
    32             bar();
    33         }
    34     }
    35 }

    结果自然也是不可预料的,需要注意的是:有可能会输出两个Victory!

    如果我们把flag=true的语句写在输出的后面的话,几率会更大,如下:

    由于这两个线程并行且共享数据,所以可能是危险的。

    解决办法:

    通过lock语句来设定排它锁。

     1 using System;
     2 using System.Threading;
     3 
     4 namespace Test
     5 {
     6     class Program
     7     {
     8         static bool flag = false;
     9         static object locker = new object();
    10 
    11         static void go( string str )
    12         {
    13             lock (locker)
    14             {
    15                 if (!flag)
    16                 {
    17                     Console.Write(str + "Victory");
    18                     flag = true;
    19                 }
    20             }
    21         }
    22 
    23         static void foo()
    24         {
    25             go("foo");
    26         }
    27 
    28         static void bar()
    29         {
    30             go("bar");
    31         }
    32 
    33         static void Main(string[] args)
    34         {
    35             new Thread(foo).Start();
    36             bar();
    37         }
    38     }
    39 }

    这样就不会有问题啦!

    仔细想一想,12306估计就是这样的吧!所以服务器压力大,总是崩溃也是可以理解的。

  • 相关阅读:
    面试官:IO 操作必须要手动关闭吗?关闭流方法是否有顺序?
    程序员大部分时间不是写代码,而是。。。
    别再用 System.currentTimeMillis() 统计耗时了,太 Low,StopWatch 好用到爆!
    Spring Boot + Querydsl 框架,大大简化复杂查询操作!!
    Java 8 中 Map 骚操作!好用到爆!!
    100 行代码搞定了 RPC 原理,大家随便问。。
    Spring Cloud 如何统一异常处理?写得太好了!
    5 款顶级 Docker GUI 工具,好用到爆!!
    60 个神级 VS Code 插件!!
    Java 8 排序的 10 个姿势,太秀了吧!同事直呼看不懂。。
  • 原文地址:https://www.cnblogs.com/huoxiayu/p/4494244.html
Copyright © 2020-2023  润新知