码迷,mamicode.com
首页 > 编程语言 > 详细

线程系列03,多线程共享数据,多线程不共享数据

时间:2014-09-19 17:30:35      阅读:290      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   io   os   使用   ar   strong   

多线程编程,有时希望每个线程的数据相互隔离互不影响,有时却希望线程间能共享数据,并保持同步。本篇体验多线程共享和不共享数据。


□ 多线程不共享数据

对于多线程,CLR到底是怎样为它们分配内存栈空间呢?是"一个萝卜一个坑",每个线程都有自己的栈空间;还是"大树底下好乘凉",所有的线程共享同一个栈空间?

我们让2个线程执行相同的静态方法,用到相同的变量,通过打印变量来求证多线程栈空间的分配情况。

    class Program
    {
        static void Main(string[] args)
        {
            new Thread(SayHi).Start();
            SayHi();
        }
        static void SayHi()
        {
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("我是线程#" + Thread.CurrentThread.ManagedThreadId + "这是我的第" +i+  "次说hello");
            }
        }
    }

bubuko.com,布布扣

虽然2个线程交叉执行,但都说了4次的hello。说明CLR为2个线程都分配了栈空间,变量i在各自的栈空间中相互不受影响。

bubuko.com,布布扣

 

□ 多线程共享数据

线程间是需要相互合作的,多个线程如何共享数据呢?

 

※ 共享实例变量

让2个线程执行同一个实例方法,看看是否可以共享对象实例的公共字段。

using System;
using System.Threading;
namespace ConsoleApplication1
{
    class Program
    {
        public int whatever;
        static void Main(string[] args)
        {
            Program p = new Program();
            new Thread(p.PrintVariable).Start();
            p.PrintVariable();
        }
        void PrintVariable()
        {
            whatever++;
            Console.WriteLine("线程#" + Thread.CurrentThread.ManagedThreadId + " 执行后whatever变量为:" +whatever);
        }
    }
}

bubuko.com,布布扣

可见,2个线程共享了Program实例的公共字段。

bubuko.com,布布扣

 

另外,关于线程间共享数据,一个绕不开的话题是:如何避免数据不同步?使用lock语句块可以解决这个问题,在同一时刻只允许有一个线程进入方法内部。这样的做法也叫”线程安全”。

    class Program
    {
        public int whatever;
        //static readonly编译期变量 在声明时赋值
        static readonly object locker = new object();
        static void Main(string[] args)
        {
            Program p = new Program();
            new Thread(p.PrintVariable).Start();
            p.PrintVariable();
        }
        void PrintVariable()
        {
            lock (locker)
            {
                whatever++;
                Console.WriteLine("线程#" + Thread.CurrentThread.ManagedThreadId + " 执行后whatever变量为:" + whatever);
            }           
        }
    }

当一个线程在lock语句块执行,另一个线程等待,等待的这个线程在那刻不消耗CPU。   

 

※ 共享静态字段

    class Program
    {
        static int whatever;
        //static readonly编译期变量 在声明时赋值
        static readonly object locker = new object();
        static void Main(string[] args)
        {
            new Thread(PrintVariable).Start();
            PrintVariable();
        }
        static void PrintVariable()
        {
            lock (locker)
            {
                whatever++;
                Console.WriteLine("线程#" + Thread.CurrentThread.ManagedThreadId + " 执行后whatever变量为:" + whatever);
            }           
        }
    }

bubuko.com,布布扣

 

总结:
○ CLR会给每个线程分配内存栈空间,栈中的变量互不影响
○ 多线程可以共享对象实例的公共成员和类的静态字段
○ 线程间共享数据需要考虑"线程安全",使用lock语句块可保证"线程安全"

 

线程系列包括:

线程系列01,前台线程,后台线程,线程同步

线程系列02,多个线程同时处理一个耗时较长的任务以节省时间

线程系列03,多线程共享数据,多线程不共享数据

线程系列03,多线程共享数据,多线程不共享数据

标签:style   blog   http   color   io   os   使用   ar   strong   

原文地址:http://www.cnblogs.com/darrenji/p/3981679.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!