您的位置:首页 > 大数据 > 人工智能

稳扎稳打Silverlight(26) - 2.0线程之Lock, Interlocked, EventWaitHandle, Monitor, ThreadStaticAttribute

2008-12-29 08:52 585 查看
[索引页]
[源码下载]

[align=center]稳扎稳打Silverlight(26) - 2.0线程之Lock, Interlocked, EventWaitHandle, Monitor, ThreadStaticAttribute[/align]

作者:webabcd

介绍

Silverlight 2.0 使用Lock, Interlocked, EventWaitHandle, Monitor来实现线程同步

    Lock - 确保代码块完成运行,而不会被其他线程中断

    Interlocked - 为多个线程共享的变量提供原子级的操作

    EventWaitHandle - 通知其他线程是否可入的类

    Monitor - 提供同步访问对象的机制

    ThreadStaticAttribute - 所指定的静态变量对每个线程都是唯一的

在线DEMO
http://www.cnblogs.com/webabcd/archive/2008/10/09/1307486.html

示例

1、Lock.xaml


<UserControl x:Class="Silverlight20.Thread.Lock"


    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 


    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">


    <StackPanel HorizontalAlignment="Left" Margin="5">




        <TextBlock x:Name="txtMsg" />




    </StackPanel>


</UserControl>



Lock.xaml.cs


using System;


using System.Collections.Generic;


using System.Linq;


using System.Net;


using System.Windows;


using System.Windows.Controls;


using System.Windows.Documents;


using System.Windows.Input;


using System.Windows.Media;


using System.Windows.Media.Animation;


using System.Windows.Shapes;




namespace Silverlight20.Thread






{


    public partial class Lock : UserControl




    

{


        // 需要被 lock 的静态变量


        private static readonly object objLock = new object();




        private static int i;




        public Lock()




        

{


            InitializeComponent();




            i = 0;




            for (int x = 0; x < 100; x++)




            

{


                // 开 100 个线程去操作静态变量 i


                System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(DoWork));


                thread.Start();


            }




            System.Threading.Thread.Sleep(3000);


            // 3 秒后 100 个线程都应该执行完毕了,取得 i 的结果


            // 做了并发处理的结果为 100 ,去掉 lock 可得到不做并发处理的结果


            txtMsg.Text = i.ToString();


        }




        private void DoWork()




        

{


            try




            

{


                // lock() - 确保代码块完成运行,而不会被其他线程中断。其参数必须为一个引用类型的对象


                lock (objLock)




                

{


                    int j = i + 1;




                    // 模拟多线程并发操作静态变量 i 的情况


                    System.Threading.Thread.Sleep(10);




                    i = j;


                }


            }


            finally




            

{


                // code


            }


        }


    }


}



2、Interlocked.xaml


<UserControl x:Class="Silverlight20.Thread.Interlocked"


    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 


    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">


    <StackPanel HorizontalAlignment="Left" Margin="5">




        <TextBlock x:Name="txtMsg" />




    </StackPanel>


</UserControl>



Interlocked.xaml.cs


using System;


using System.Collections.Generic;


using System.Linq;


using System.Net;


using System.Windows;


using System.Windows.Controls;


using System.Windows.Documents;


using System.Windows.Input;


using System.Windows.Media;


using System.Windows.Media.Animation;


using System.Windows.Shapes;




namespace Silverlight20.Thread






{


    public partial class Interlocked : UserControl




    

{


        private static int i;




        public Interlocked()




        

{


            InitializeComponent();




            i = 0;




            for (int x = 0; x < 100; x++)




            

{


                // 开 100 个线程去操作静态变量 i


                System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(DoWork));


                thread.Start();


            }




            System.Threading.Thread.Sleep(1000);


            // 1 秒后 100 个线程都应该执行完毕了,取得 i 的结果


            txtMsg.Text = i.ToString();


        }




        private void DoWork()




        

{


            try




            

{


                // Interlocked - 为多个线程共享的变量提供原子级的操作(避免并发问题)




                // i 加 1


                System.Threading.Interlocked.Increment(ref i);




                // i 减 1


                System.Threading.Interlocked.Decrement(ref i);




                // i 加 1


                System.Threading.Interlocked.Add(ref i, 1);




                // 如果 i 等于 100 ,则将 i 赋值为 101


                System.Threading.Interlocked.CompareExchange(ref i, 101, 100); 




                // 将 i 赋值为 1000


                // System.Threading.Interlocked.Exchange(ref i, 1000);


            }


            finally




            

{


                // code


            }


        }


    }


}



3、EventWaitHandle.xaml


<UserControl x:Class="Silverlight20.Thread.EventWaitHandle"


    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 


    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">


    <StackPanel HorizontalAlignment="Left" Margin="5">




        <TextBlock x:Name="txtAutoResetEvent" />


        


        <TextBlock x:Name="txtManualResetEvent" />




    </StackPanel>


</UserControl>



EventWaitHandle.xaml.cs


using System;


using System.Collections.Generic;


using System.Linq;


using System.Net;


using System.Windows;


using System.Windows.Controls;


using System.Windows.Documents;


using System.Windows.Input;


using System.Windows.Media;


using System.Windows.Media.Animation;


using System.Windows.Shapes;




namespace Silverlight20.Thread






{


    public partial class EventWaitHandle : UserControl




    

{


        // AutoResetEvent(bool state) - 通知其他线程是否可入的类,自动 Reset()


        //     bool state - 是否为终止状态,即是否禁止其他线程入内


        private System.Threading.AutoResetEvent autoResetEvent = 


            new System.Threading.AutoResetEvent(false);




        // ManualResetEvent(bool state) - 通知其他线程是否可入的类,手动 Reset()


        //     bool state - 是否为终止状态,即是否禁止其他线程入内


        private System.Threading.ManualResetEvent manualResetEvent = 


            new System.Threading.ManualResetEvent(false);




        private static int i;




        public EventWaitHandle()




        

{


            InitializeComponent();




            // 演示 AutoResetEvent


            AutoResetEventDemo();




            // 演示 ManualResetEvent


            ManualResetEventDemo();


        }




        private void AutoResetEventDemo()




        

{


            i = 0;




            for (int x = 0; x < 100; x++)




            

{


                // 开 100 个线程去操作静态变量 i


                System.Threading.Thread thread =


                    new System.Threading.Thread(new System.Threading.ThreadStart(AutoResetEventDemoCallback));


                thread.Start();




                // 阻塞当前线程,直到 AutoResetEvent 发出 Set() 信号


                autoResetEvent.WaitOne();


            }




            System.Threading.Thread.Sleep(1000);


            // 1 秒后 100 个线程都应该执行完毕了,取得 i 的结果


            txtAutoResetEvent.Text = i.ToString();


        }




        private void AutoResetEventDemoCallback()




        

{


            try




            

{


                int j = i + 1;




                // 模拟多线程并发操作静态变量 i 的情况


                System.Threading.Thread.Sleep(5);




                i = j;


            }


            finally




            

{


                // 发出 Set() 信号,以释放 AutoResetEvent 所阻塞的线程


                autoResetEvent.Set();


            }


        }






        private void ManualResetEventDemo()




        

{


            i = 0;




            for (int x = 0; x < 100; x++)




            

{


                // Reset() - 将 ManualResetEvent 变为非终止状态,即由此线程控制 ManualResetEvent,


                //     其他线程排队,直到 ManualResetEvent 发出 Set() 信号(AutoResetEvent 在 Set() 时会自动 Reset())


                manualResetEvent.Reset();




                // 开 100 个线程去操作静态变量 i


                System.Threading.Thread thread =


                    new System.Threading.Thread(new System.Threading.ThreadStart(ManualResetEventDemoCallback));


                thread.Start();




                // 阻塞当前线程,直到 ManualResetEvent 发出 Set() 信号


                manualResetEvent.WaitOne();


            }




            System.Threading.Thread.Sleep(1000);


            // 1 秒后 100 个线程都应该执行完毕了,取得 i 的结果


            txtManualResetEvent.Text = i.ToString();


        }




        private void ManualResetEventDemoCallback()




        

{


            try




            

{


                int j = i + 1;




                // 模拟多线程并发操作静态变量 i 的情况


                System.Threading.Thread.Sleep(5);




                i = j;


            }


            finally




            

{


                // 发出 Set() 信号,以释放 ManualResetEvent 所阻塞的线程,同时 ManualResetEvent 变为终止状态)


                manualResetEvent.Set();


            }


        }


    }


}



4、Monitor.xaml


<UserControl x:Class="Silverlight20.Thread.Monitor"


    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 


    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">


    <StackPanel HorizontalAlignment="Left" Margin="5">




        <TextBlock x:Name="txtMsg" />




    </StackPanel>


</UserControl>



Monitor.xaml.cs


using System;


using System.Collections.Generic;


using System.Linq;


using System.Net;


using System.Windows;


using System.Windows.Controls;


using System.Windows.Documents;


using System.Windows.Input;


using System.Windows.Media;


using System.Windows.Media.Animation;


using System.Windows.Shapes;




namespace Silverlight20.Thread






{


    public partial class Monitor : UserControl




    

{


        private static readonly object objLock = new object();


        private static int i;


        


        public Monitor()




        

{


            InitializeComponent();




            i = 0;




            for (int x = 0; x < 100; x++)




            

{


                // 开 100 个线程去操作静态变量 i


                System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(DoWork));


                thread.Start();


            }




            System.Threading.Thread.Sleep(1000);


            // 1 秒后 100 个线程都应该执行完毕了,取得 i 的结果


            txtMsg.Text = i.ToString();


        }




        private void DoWork()




        

{


            try




            

{


                // Monitor - 提供同步访问对象的机制




                // Enter() - 在指定对象上获取排他锁


                System.Threading.Monitor.Enter(objLock);




                int j = i + 1;




                // 模拟多线程并发操作静态变量 i 的情况


                System.Threading.Thread.Sleep(5);




                i = j;




                // Exit() - 释放指定对象上的排他锁


                System.Threading.Monitor.Exit(objLock);


            }


            finally




            

{


                // code


            }


        }


    }


}

5、ThreadStaticAttribute.xaml


<UserControl x:Class="Silverlight20.Thread.ThreadStaticAttribute"


    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 


    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">


    <StackPanel HorizontalAlignment="Left" Margin="5">


    


        <TextBlock x:Name="txtMsg" />


        


        <TextBlock x:Name="txtMsg2" />




    </StackPanel>


</UserControl>



ThreadStaticAttribute.xaml.cs


using System;


using System.Collections.Generic;


using System.Linq;


using System.Net;


using System.Windows;


using System.Windows.Controls;


using System.Windows.Documents;


using System.Windows.Input;


using System.Windows.Media;


using System.Windows.Media.Animation;


using System.Windows.Shapes;




namespace Silverlight20.Thread






{


    public partial class ThreadStaticAttribute : UserControl




    

{


        // ThreadStatic - 所指定的静态变量对每个线程都是唯一的


        [System.ThreadStatic]


        private static int value;




        // 一般的静态变量,对每个线程都是共用的


        private static int value2;




        public ThreadStaticAttribute()




        

{


            InitializeComponent();




            Demo();


        }




        void Demo()




        

{


            System.Threading.Thread thread = new System.Threading.Thread(DoWork);


            thread.Name = "线程1";


            thread.Start();




            System.Threading.Thread.Sleep(100);




            System.Threading.Thread thread2 = new System.Threading.Thread(DoWork2);


            thread2.Name = "线程2";


            thread2.Start();




        }




        void DoWork()




        

{


            for (int i = 0; i < 10; i++)




            

{


                // 线程1对静态变量的操作


                value++;


                value2++;


            }




            string s = value.ToString(); // value - 本线程独有的静态变量


            string s2 = value2.ToString(); // value2 - 所有线程共用的静态变量






            this.Dispatcher.BeginInvoke(delegate 

{ txtMsg.Text = s + " - " + s2; });


            // this.Dispatcher.BeginInvoke(delegate { txtMsg.Text = value + " - " + value2; }); // 在UI线程上调用,所以value值为UI线程上的value值,即 0 


        }




        void DoWork2()




        

{


            for (int i = 0; i < 10; i++)




            

{


                // 线程2对静态变量的操作


                value++;


                value2++;


            }




            string s = value.ToString(); // value - 本线程独有的静态变量


            string s2 = value2.ToString(); // value2 - 所有线程共用的静态变量






            this.Dispatcher.BeginInvoke(delegate 

{ txtMsg2.Text = s + " - " + s2; });


            // this.Dispatcher.BeginInvoke(delegate { txtMsg2.Text = value + " - " + value2; }); // 在UI线程上调用,所以value值为UI线程上的value值,即 0 


        }


    }


}



OK
[源码下载]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐