zoukankan      html  css  js  c++  java
  • 线程同步

    基本概念:

    在应用程序中使用多个线程的一个好处是每个线程都可以异步执行。对于 Windows 应用程序,耗时的任务可以在后台执行,而使应用程序窗口和控件保持响应。对于服务器应用程序,多线程处理提供了用不同线程处理每个传入请求的能力。否则,在完全满足前一个请求之前,将无法处理每个新请求。

    然而,线程的异步特性意味着必须协调对资源(如文件句柄、网络连接和内存)的访问。否则,两个或更多的线程可能在同一时间访问相同的资源,而每个线程都不知道其他线程的操作。结果将产生不可预知的数据损坏。

    对于整数数据类型的简单操作,可以用 Interlocked 类的成员来实现线程同步。对于其他所有数据类型和非线程安全的资源,只有使用本主题中的结构才能安全地执行多线程处理。

    线程同步的方法有很多,我们先看看join方法是如何实现同步的

    参考:http://www.cnblogs.com/lxblog/archive/2012/12/26/2833974.html

    class Program
        {
            private static Thread thread1;
            private static Thread thread2;
    
            static void Main(string[] args)
            {
                thread1=new Thread(new ThreadStart(Thread1Method));
                thread2=new Thread(new ThreadStart(Thread2Method));
                thread1.Start();
                thread1.Join();
                thread2.Start();
                thread2.Join();
    
    
            }
    
            public static void Thread1Method()
            {
    
                for (int i = 0; i < 5; i++)
                {
                    Thread.Sleep(1000);
                    Console.WriteLine("线程1正在运行");
                }
                
            }
    
            public static void Thread2Method()
            {
                for (int i = 0; i < 5; i++)
                {
                    Thread.Sleep(1000);
                    Console.WriteLine("线程2正在运行");
                }
            }
        }

    这是一个简单的demo,运行结果是这样的

    线程1正在运行
    线程1正在运行
    线程1正在运行
    线程1正在运行
    线程1正在运行
    线程2正在运行
    线程2正在运行
    线程2正在运行
    线程2正在运行
    线程2正在运行
    请按任意键继续.

    线程1执行完才执行线程2

    当然join方法可以有参数,用以设置阻塞时间

    http://www.cnblogs.com/michaelxu/archive/2008/09/20/1293716.html

    lock关键字

    lock是一种比较好用的简单的线程同步方式,它是通过为给定对象获取互斥锁来实现同步的。它可以保证当一个线程在关键代码段的时候,另一个线程不会进来,它只能等待,等到那个线程对象被释放,也就是说线程出了临界区。用法:

    lock(codeA)//codeA是被锁住的对象,在被锁住时这个对象不能被其他线程使用
    {
     codeB//codeB执行完后才释放对象其他线程才能访问codeB
    }
     internal class Program
        {
    
            private static Thread thread1;
            private static Thread thread2;
            private static int count = 0;
    
            private static void Main(string[] args)
            {
                thread1 = new Thread(new ThreadStart(Thread1Method));
                thread2 = new Thread(new ThreadStart(Thread2Method));
                thread1.Start();
                thread2.Start();
                Console.ReadKey();
            }
    
            public static void Thread1Method()
            {
                Method("thread1");
            }
            static object obj=new object();
            public static void Method(string threadName)
            {
                
                lock (obj)
                {
                    Console.WriteLine(threadName + "进入锁定区域");
                    for (int i = 0; i < 5; i++)
                    {
                        Thread.Sleep(1000);
    
                        Console.WriteLine(string.Format("{0},{1}", count++, threadName));
                    }
                    Console.WriteLine(threadName + "退出锁定区域");
    
                }
    
    
    
            }
    
            public static void Thread2Method()
            {
                Method("thread2");
    
            }
    
    
        }

    运行结果:

    thread1进入锁定区域
    0,thread1
    1,thread1
    2,thread1
    3,thread1
    4,thread1
    thread1退出锁定区域
    thread2进入锁定区域
    5,thread2
    6,thread2
    7,thread2
    8,thread2
    9,thread2
    thread2退出锁定区域
    请按任意键继续. . .

    System.Threading.Interlocked

      对于整数数据类型的简单操作,可以用 Interlocked 类的成员来实现线程同步,存在于System.Threading命名空间。Interlocked类有以下方法:Increment , Decrement , Exchange 和CompareExchange 。使用Increment 和Decrement 可以保证对一个整数的加减为一个原子操作。Exchange 方法自动交换指定变量的值。CompareExchange 方法组合了两个操作:比较两个值以及根据比较的结果将第三个值存储在其中一个变量中。比较和交换操作也是按原子操作执行的。如:

    int i = 0 ;
    System.Threading.Interlocked.Increment( ref i);
    Console.WriteLine(i);
    System.Threading.Interlocked.Decrement( ref i);
    Console.WriteLine(i);
    System.Threading.Interlocked.Exchange( ref i, 100 );
    Console.WriteLine(i);
    System.Threading.Interlocked.CompareExchange( ref i, 10 , 100 );

    Monitor

      Monitor类提供了与lock类似的功能,不过与lock不同的是,它能更好的控制同步块,当调用了Monitor的Enter(Object o)方法时,会获取o的独占权,直到调用Exit(Object o)方法时,才会释放对o的独占权,可以多次调用Enter(Object o)方法,只需要调用同样次数的Exit(Object o)方法即可,Monitor类同时提供了TryEnter(Object o,[int])的一个重载方法,该方法尝试获取o对象的独占权,当获取独占权失败时,将返回false。

      但使用 lock 通常比直接使用 Monitor 更可取,一方面是因为 lock 更简洁,另一方面是因为 lock 确保了即使受保护的代码引发异常,也可以释放基础监视器。这是通过 finally 中调用Exit来实现的。事实上,lock 就是用 Monitor 类来实现的。下面两段代码是等效的:

    lock (x)
    {
    DoSomething();
    }
    等效于
    
    object obj = ( object )x;
    System.Threading.Monitor.Enter(obj);
    try 
    {
    DoSomething();
    }
    finally 
    {
    System.Threading.Monitor.Exit(obj);
    }
  • 相关阅读:
    codeforces 632F. Magic Matrix
    codeforces 632D. Longest Subsequence 筛法
    移动端项目开发需要注意的问题
    input框、按钮组间的去除空格的解决方案
    radio 和checkbox与文字对齐问题
    怎样设置webstorm localhost为本地ip
    The number of steps(概率dp)
    C++ 面试常见问题
    禅者初心
    Hope
  • 原文地址:https://www.cnblogs.com/jixinyu/p/4298810.html
Copyright © 2011-2022 走看看