最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#多線程基礎(chǔ)知識(shí)匯總

 更新時(shí)間:2020年07月03日 09:11:23   作者:萌萌丶小魔王  
這篇文章主要介紹了C#多線程基礎(chǔ)知識(shí)的相關(guān)資料,文中示例代碼非常詳細(xì),幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下

最近自己寫了個(gè)小爬蟲,里面用到了多線程技術(shù),忽然發(fā)現(xiàn)對(duì)此技術(shù)竟然有些陌生了,于是乎開始瘋狂的去問度娘,在此記錄下來(lái),以便自己和各位小伙伴們學(xué)習(xí)。

一、什么是線程

一個(gè)應(yīng)用程序就相當(dāng)于一個(gè)進(jìn)程,進(jìn)程擁有應(yīng)用程序的所有資源進(jìn)程包括線程,進(jìn)程的資源被線程共享,但不擁有線程。我們可以打開電腦中的任務(wù)管理器,運(yùn)行的.exe都是一個(gè)進(jìn)程,里面的分支是線程。

二、多線程

多線程其實(shí)就是進(jìn)程中一段并行運(yùn)行的代碼

1. 創(chuàng)建并啟動(dòng)線程

static void Main()
    {
      //獲取線程Id
      var threadId = Thread.CurrentThread.ManagedThreadId;
      var thread = new Thread(Test1);
      thread.Start();

      Console.WriteLine(threadId + "_Main()");
      Console.Read();
    }

    /// <summary>
    /// 測(cè)試方法
    /// </summary>
    private static void Test1()
    {
      //獲取線程Id
      var threadId = Thread.CurrentThread.ManagedThreadId;
      Console.WriteLine(threadId + "_Test()");
      for (int i = 0; i < 10; i++)
      {
        Console.WriteLine(threadId + "_" + i);
      }
    }

結(jié)果:

2、暫定線程諾干時(shí)間

static void Main()
    {
      //獲取線程Id
      var threadId = Thread.CurrentThread.ManagedThreadId;
      var thread = new Thread(Test1);
      thread.Start();
      Console.WriteLine($"主線程Id{threadId}_Main()");
      Console.Read();
    }

    /// <summary>
    /// 測(cè)試方法
    /// </summary>
    private static void Test1()
    {
      //獲取線程Id
      var threadId = Thread.CurrentThread.ManagedThreadId;
      Console.WriteLine($"輔線程Id{threadId}_Test()");
      for (int i = 0; i < 10; i++)
      {
        Thread.Sleep(1000);//單位毫秒
        Console.WriteLine($"輔線程Id{threadId}_{DateTime.Now}");
      }
    }

結(jié)果:

3、線程合并

Thread.Join操作會(huì)阻塞當(dāng)前線程,等待子線程完成后再進(jìn)行運(yùn)行。

static void Main()
    {
      //獲取線程Id
      var threadId = Thread.CurrentThread.ManagedThreadId;
      var thread = new Thread(Test1);
      thread.Start();
      Console.WriteLine($"主線程Id{threadId}_Main()1");
      thread.Join();
      Console.WriteLine($"主線程Id{threadId}_Main()2");
      Console.Read();
    }

    /// <summary>
    /// 測(cè)試方法
    /// </summary>
    private static void Test1()
    {
      //獲取線程Id
      var threadId = Thread.CurrentThread.ManagedThreadId;
      Console.WriteLine($"輔線程Id{threadId}_Test()");
      for (int i = 0; i < 10; i++)
      {
        Thread.Sleep(1000);//單位毫秒
        Console.WriteLine($"輔線程Id{threadId}_{DateTime.Now}");
      }
    }

結(jié)果:

4、線程終止

static void Main()
    {
      //獲取線程Id
      var threadId = Thread.CurrentThread.ManagedThreadId;
      var thread = new Thread(Test1);
      thread.Start();
      Console.WriteLine($"主線程Id{threadId}_Main()1");
      Thread.Sleep(3000);
      thread.Abort();
      Console.WriteLine($"主線程Id{threadId}_Main()2");
      Console.Read();
    }

    /// <summary>
    /// 測(cè)試方法
    /// </summary>
    private static void Test1()
    {
      //獲取線程Id
      var threadId = Thread.CurrentThread.ManagedThreadId;
      Console.WriteLine($"輔線程Id{threadId}_Test()");
      for (int i = 0; i < 10; i++)
      {
        Thread.Sleep(1000);//單位毫秒
        Console.WriteLine($"輔線程Id{threadId}_{DateTime.Now}");
      }
    }

結(jié)果:

 5、線程中的參數(shù)傳遞

static void Main()
    {
      //獲取線程Id
      var threadId = Thread.CurrentThread.ManagedThreadId;
      Console.WriteLine($"主線程Id{threadId}_Main()");
      //第一種參數(shù)傳遞方式
      var thread1 = new Thread(() => Test1("小魔王"));
      thread1.Start();

      //第二種參數(shù)傳遞方式(參數(shù)只能是一個(gè),object類型)
      var parameterizedThreadStart = new ParameterizedThreadStart(Test2);
      var thread2 = new Thread(parameterizedThreadStart);
      thread2.Start("大魔王");
      Console.Read();
    }

    /// <summary>
    /// 測(cè)試方法
    /// </summary>
    private static void Test1(string name)
    {
      //獲取線程Id
      var threadId = Thread.CurrentThread.ManagedThreadId;
      Console.WriteLine($"輔線程Id{threadId}_我的名字叫:{name}");
    }

    /// <summary>
    /// 測(cè)試方法
    /// </summary>
    private static void Test2(object name)
    {
      //獲取線程Id
      var threadId = Thread.CurrentThread.ManagedThreadId;
      Console.WriteLine($"輔線程Id{threadId}_我的名字叫:{name}");
    }

結(jié)果:

還有其他的傳遞方式,在此先不做說(shuō)明了,這里只介紹Thread提供的這么幾種。

6、線程安全和線程鎖Lock

線程安全就是多線程訪問時(shí),采用了加鎖機(jī)制,當(dāng)一個(gè)線程訪問該類的某個(gè)數(shù)據(jù)時(shí),進(jìn)行保護(hù),其他線程不能進(jìn)行訪問直到該線程讀取完,其他線程才可使用。線程安全情況下,不會(huì)出現(xiàn)數(shù)據(jù)不一致或者數(shù)據(jù)污染的問題。 線程不安全就是不提供數(shù)據(jù)訪問保護(hù),有可能出現(xiàn)多個(gè)線程先后更改數(shù)據(jù)造成所得到的數(shù)據(jù)是臟數(shù)據(jù)! 若每個(gè)線程中對(duì)全局變量、靜態(tài)變量只有讀操作,而無(wú)寫操作,一般來(lái)說(shuō),這個(gè)全局變量是線程安全的;若有多個(gè)線程同時(shí)執(zhí)行寫操作,一般都需要考慮線程同步,否則的話就可能影響線程安全。

lock 關(guān)鍵字通過獲取指定對(duì)象的互斥鎖,將語(yǔ)句塊標(biāo)記為臨界區(qū),執(zhí)行語(yǔ)句然后釋放該鎖。

lock 確保當(dāng)一個(gè)線程位于代碼的臨界區(qū)時(shí),另一個(gè)線程不進(jìn)入臨界區(qū)。如果其他線程試圖進(jìn)入鎖定的代碼,則它將一直等待(即被阻止),直到該對(duì)象被釋放。使用Lock,會(huì)導(dǎo)致整個(gè)應(yīng)用程序串行化,降低程序的并發(fā)能力,影響性能。

到底什么場(chǎng)景下要使用lock保證線程安全:該串行就串行,該并行就并行。

加鎖前:

public static int i = 1000000;
    static void Main()
    {
      //獲取線程Id
      var threadId = Thread.CurrentThread.ManagedThreadId;
      for (int j = 0; j < 2; j++)
      {
        var thread = new Thread(Test1);
        thread.Start();
      }
      Console.Read();
    }

    /// <summary>
    /// 測(cè)試方法
    /// </summary>
    private static void Test1()
    {
      //獲取線程Id
      var threadId = Thread.CurrentThread.ManagedThreadId;

      Console.WriteLine($"輔線程Id{threadId}_i初始值:{i}");
      int count = 0;
      for (int j = 0; j < 1000000; j++)
      {
        i--;
        count++;
      }
      Console.WriteLine($"輔線程Id{threadId}_運(yùn)行次數(shù):{count}");
      Console.WriteLine($"輔線程Id{threadId}_i結(jié)束值:{i}");
    }

結(jié)果:

加鎖后:

public static int i = 1000000;
    private readonly static object objLock = new object();
    static void Main()
    {
      //獲取線程Id
      var threadId = Thread.CurrentThread.ManagedThreadId;
      for (int j = 0; j < 2; j++)
      {
        var thread = new Thread(Test1);
        thread.Start();
      }
      Console.Read();
    }

    private static void Test1()
    {
      //獲取線程Id
      var threadId = Thread.CurrentThread.ManagedThreadId;

      int count = 0;
      lock (objLock)
      {
        Console.WriteLine($"輔線程Id{threadId}_i初始值:{i}");
        for (int j = 0; j < 1000000; j++)
        {
          i--;
          count++;
        }
      }
      Console.WriteLine($"輔線程Id{threadId}_運(yùn)行次數(shù):{count}");
      Console.WriteLine($"輔線程Id{threadId}_i結(jié)束值:{i}");
    }

結(jié)果:

好啦,今天關(guān)于線程的知識(shí)就分箱到這里啦。

到此這篇關(guān)于C#多線程基礎(chǔ)知識(shí)匯總的文章就介紹到這了,更多相關(guān)C#多線程基礎(chǔ)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

榆林市| 绵竹市| 闸北区| 深圳市| 谢通门县| 沿河| 昔阳县| 姜堰市| 哈密市| 黄石市| 宜州市| 郯城县| 江华| 兴仁县| 宜宾市| 武胜县| 濮阳市| 合山市| 隆林| 河池市| 吉隆县| 阳山县| 渭南市| 通榆县| 鄢陵县| 余庆县| 兴海县| 娄烦县| 铁力市| 招远市| 柞水县| 肇东市| 巫山县| 新巴尔虎右旗| 乳源| 平定县| 行唐县| 忻城县| 雷山县| 滕州市| 武定县|