• 2.0线程之Lock, Interlocked, EventWaitHandle, Monitor, ThreadStaticAttribute


    介绍
    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, 101100); 

                    
    // 将 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 
            }

        }

    }


  • 相关阅读:
    关于前端基础框架的思考和尝试
    通过当前IP获取当前网卡的MAC地址
    shell及脚本2——shell 环境及命令
    shell及脚本1——变量
    linux显示git commit id,同时解决insmod模块时版本不一致导致无法加载问题
    大于16MB的QSPI存放程序引起的ZYNQ重启风险
    insmod模块的几种常见错误
    shell及脚本3——正则表达式
    修改/etc/profile和/etc/environment导致图形界面无法登陆的问题
    Sql 2008的merge关键字
  • 原文地址:https://www.cnblogs.com/bingyun84/p/1499173.html
Copyright © 2020-2023  润新知