zoukankan      html  css  js  c++  java
  • .NET多线程小记(6):线程同步

    同步块的机制:

    • 在.NET被加载时初始化同步块数组
    • 每一个被分配在堆上的对象都会包含两个额外的字段,其中一个存储类型指针,而另外一个就是同步块索引,初始时被赋值为-1.
    • 当一个线程试图使用该对象进入同步时,会检查该对象的同步索引。如果索引为负数,则会在同步块数组中寻找或者新建一个同步块,并且把同步块的索引值写入该对象的同步索引中。如果该对象的同步索引不为负值,则找到该对象的同步块并且检查是否有其他线程在使用该同步块,如果有则进入等待状态,如果没有则声明使用该同步块。
    • 当一个对象退出同步时,该对象的同步索引被赋值为-1,并且对应的同步块数组内的同步块被视为不再使用。

    image

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    
    namespace MultiThreadTest
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("测试静态方法同步?");
                for (int i = 0; i < 5; i++)
                {
                    Thread t = new Thread(Lock.Add1);
                    t.Start();               
                }
                Thread.Sleep(10 * 1000);
                Console.WriteLine("测试成成员方法同步");
                Lock l = new Lock();
                for (int i = 0; i < 5; i++)
                {
                    Thread t = new Thread(l.Add2);
                    t.Start();
                }
                Console.Read();
            }        
        }
    
        public class Lock
        {
            // 用来同步静态方法
            private static object o1 = new object();
            private static int i1 = 0;
    
            // 用来同步成员方法
            private object o2 = new object();
            private int i2 = 0;
    
    
            public static void Add1(object state)
            {
                lock (o1)
                {
                    Console.WriteLine("before add:i1 = {0}", i1);
                    Thread.Sleep(1000);
                    i1++;
                    Console.WriteLine("after add :i1 = {0}", i1);
                }            
            }
    
            public  void Add2(object state)
            {
                lock (o2)
                {
                    Console.WriteLine("before add:i1 = {0}", i2);
                    Thread.Sleep(1000);
                    i2++;
                    Console.WriteLine("after add :i1 = {0}", i2);
                }
            }    
        }
    }
    image

    注意:对静态方法的同步,一般采用静态私有的引用成员,而对成员方法的同步,一般采用私有的引用成员。值类型的对象非配在堆栈上,没有同步索引字段,所以不能用来进行同步。

  • 相关阅读:
    [SDOI2009]生日礼物(单调队列)
    [luogu1638]逛画展(单调队列)
    【最短路】·SPFA算法实现
    [UVA10474]大理石在哪儿
    【转载】C++中string erase函数的使用
    【转载】高精度减法的OP写法
    【转载】ST表
    串门赛: NOIP2016模拟赛——By Marvolo 丢脸记
    Bzoj 3813 奇数国 题解 数论+线段树+状压
    Bzoj 2064 分裂 题解
  • 原文地址:https://www.cnblogs.com/cnblogsfans/p/1597453.html
Copyright © 2011-2022 走看看