[索引页]
[×××]


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


作者: webabcd


介绍
Silverlight 2.0 使用Lock, Interlocked, EventWaitHandle, Monitor来实现线程同步
    Lock - 确保代码块完成运行,而不会被其他线程中断
    Interlocked - 为多个线程共享的变量提供原子级的操作
    EventWaitHandle - 通知其他线程是否可入的类
    Monitor - 提供同步访问对象的机制
    ThreadStaticAttribute - 所指定的静态变量对每个线程都是唯一的


在线DEMO
http://webabcd.blog.51cto.com/1787395/342779


示例
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
InBlock.gif using System;
InBlock.gif using System.Collections.Generic;
InBlock.gif using System.Linq;
InBlock.gif using System.Net;
InBlock.gif using System.Windows;
InBlock.gif using System.Windows.Controls;
InBlock.gif using System.Windows.Documents;
InBlock.gif using System.Windows.Input;
InBlock.gif using System.Windows.Media;
InBlock.gif using System.Windows.Media.Animation;
InBlock.gif using System.Windows.Shapes;
InBlock.gif
InBlock.gif namespace Silverlight20.Thread
InBlock.gif{
InBlock.gif         public partial class Lock : UserControl
InBlock.gif        {
InBlock.gif                 // 需要被 lock 的静态变量
InBlock.gif                 private static readonly object objLock = new object();
InBlock.gif
InBlock.gif                 private static int i;
InBlock.gif
InBlock.gif                 public Lock()
InBlock.gif                {
InBlock.gif                        InitializeComponent();
InBlock.gif
InBlock.gif                        i = 0;
InBlock.gif
InBlock.gif                         for ( int x = 0; x < 100; x++)
InBlock.gif                        {
InBlock.gif                                 // 开 100 个线程去操作静态变量 i
InBlock.gif                                System.Threading.Thread thread = new System.Threading.Thread( new System.Threading.ThreadStart(DoWork));
InBlock.gif                                thread.Start();
InBlock.gif                        }
InBlock.gif
InBlock.gif                        System.Threading.Thread.Sleep(3000);
InBlock.gif                         // 3 秒后 100 个线程都应该执行完毕了,取得 i 的结果
InBlock.gif                         // 做了并发处理的结果为 100 ,去掉 lock 可得到不做并发处理的结果
InBlock.gif                        txtMsg.Text = i.ToString();
InBlock.gif                }
InBlock.gif
InBlock.gif                 private void DoWork()
InBlock.gif                {
InBlock.gif                         try
InBlock.gif                        {
InBlock.gif                                 // lock() - 确保代码块完成运行,而不会被其他线程中断。其参数必须为一个引用类型的对象
InBlock.gif                                 lock (objLock)
InBlock.gif                                {
InBlock.gif                                         int j = i + 1;
InBlock.gif
InBlock.gif                                         // 模拟多线程并发操作静态变量 i 的情况
InBlock.gif                                        System.Threading.Thread.Sleep(10);
InBlock.gif
InBlock.gif                                        i = j;
InBlock.gif                                }
InBlock.gif                        }
InBlock.gif                         finally
InBlock.gif                        {
InBlock.gif                                 // code
InBlock.gif                        }
InBlock.gif                }
InBlock.gif        }
InBlock.gif}
 
 
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
InBlock.gif using System;
InBlock.gif using System.Collections.Generic;
InBlock.gif using System.Linq;
InBlock.gif using System.Net;
InBlock.gif using System.Windows;
InBlock.gif using System.Windows.Controls;
InBlock.gif using System.Windows.Documents;
InBlock.gif using System.Windows.Input;
InBlock.gif using System.Windows.Media;
InBlock.gif using System.Windows.Media.Animation;
InBlock.gif using System.Windows.Shapes;
InBlock.gif
InBlock.gif namespace Silverlight20.Thread
InBlock.gif{
InBlock.gif         public partial class Interlocked : UserControl
InBlock.gif        {
InBlock.gif                 private static int i;
InBlock.gif
InBlock.gif                 public Interlocked()
InBlock.gif                {
InBlock.gif                        InitializeComponent();
InBlock.gif
InBlock.gif                        i = 0;
InBlock.gif
InBlock.gif                         for ( int x = 0; x < 100; x++)
InBlock.gif                        {
InBlock.gif                                 // 开 100 个线程去操作静态变量 i
InBlock.gif                                System.Threading.Thread thread = new System.Threading.Thread( new System.Threading.ThreadStart(DoWork));
InBlock.gif                                thread.Start();
InBlock.gif                        }
InBlock.gif
InBlock.gif                        System.Threading.Thread.Sleep(1000);
InBlock.gif                         // 1 秒后 100 个线程都应该执行完毕了,取得 i 的结果
InBlock.gif                        txtMsg.Text = i.ToString();
InBlock.gif                }
InBlock.gif
InBlock.gif                 private void DoWork()
InBlock.gif                {
InBlock.gif                         try
InBlock.gif                        {
InBlock.gif                                 // Interlocked - 为多个线程共享的变量提供原子级的操作(避免并发问题)
InBlock.gif
InBlock.gif                                 // i 加 1
InBlock.gif                                System.Threading.Interlocked.Increment( ref i);
InBlock.gif
InBlock.gif                                 // i 减 1
InBlock.gif                                System.Threading.Interlocked.Decrement( ref i);
InBlock.gif
InBlock.gif                                 // i 加 1
InBlock.gif                                System.Threading.Interlocked.Add( ref i, 1);
InBlock.gif
InBlock.gif                                 // 如果 i 等于 100 ,则将 i 赋值为 101
InBlock.gif                                System.Threading.Interlocked.CompareExchange( ref i, 101, 100);    
InBlock.gif
InBlock.gif                                 // 将 i 赋值为 1000
InBlock.gif                                 // System.Threading.Interlocked.Exchange(ref i, 1000);
InBlock.gif                        }
InBlock.gif                         finally
InBlock.gif                        {
InBlock.gif                                 // code
InBlock.gif                        }
InBlock.gif                }
InBlock.gif        }
InBlock.gif}