zoukankan      html  css  js  c++  java
  • 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 
            }

        }

    }


  • 相关阅读:
    Linux 共享库
    使用Visual Studio(VS)开发Qt程序代码提示功能的实现(转)
    ZOJ 3469 Food Delivery(区间DP)
    POJ 2955 Brackets (区间DP)
    HDU 3555 Bomb(数位DP)
    HDU 2089 不要62(数位DP)
    UESTC 1307 windy数(数位DP)
    HDU 4352 XHXJ's LIS(数位DP)
    POJ 3252 Round Numbers(数位DP)
    HDU 2476 String painter (区间DP)
  • 原文地址:https://www.cnblogs.com/bingyun84/p/1499173.html
Copyright © 2011-2022 走看看