微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

  [索引页]
[源码下载]

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

作者: webabcd
介绍
Silverlight 2.0 使用Lock,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

@H_494_3404@

{

    
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
[源码下载]

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐