乱涂C#多线程05

【文章标题】: 乱涂C#多线程05
【文章作者】: 有酒醉
【作者邮箱】: wuqr32@sina.com
【下载地址】: 自己搜索下载
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
记住,我们只能使用监督程序同步访问对象引用,而不是值类型.当Monitor.Enter接收值类型时,它首先将进行一次封箱,每一次封箱产生新的对象,这将不会导致同步访问.
 
示例 - 传递值类型 
//  CValueTypeDemo.cpp
//  Author by Yzl
# using   <  mscorlib.dll  >
using   namespace  System;
using   namespace  System::Threading;

#pragma  managed
__gc 
class   CValueTypeDemo
{
    
public:
        
static void ThreadProc(Object * state)
        
{
            Thread::Sleep(
500);
            Console::WriteLine(S
"Object:{0}",state->ToString());
            Object __pin 
*temp = __box(x);
            unsigned 
char *ix = (unsigned char*)temp;
            
            
try
            
{
                Monitor::Enter(temp);
                WriteMemoryContents(ix 
- 4,16);
            }

            
catch(Exception *ex)
            
{
                Console::WriteLine(ex
->ToString());    
            }

            __finally
            
{
                
//Monitor::Exit(temp);    
            }

            
        }

        
static void WriteMemoryContents(unsigned char*startAddress,int nBytes)
        
{
            
for (int i = 0; i < nBytes; i ++)
            
{
                
if (i % 8 == 0)
                    Console::Write(
"Address {0:x}:",__box((int)(startAddress) + i));
                
if (startAddress[i] < 16)
                    Console::Write(
"0");
                Console::Write(
"{0:x}",__box(startAddress[i]));    
                
if (i % 4 == 3)
                    Console::Write(
"  ");
                
if (i % 8 == 7)
                    Console::WriteLine();
                    
            }

            Console::WriteLine();    
        }

    
private:
        
static Int32 x = 5;
}
;

#pragma  managed
int  main()
{
    ThreadPool::QueueUserWorkItem(
new WaitCallback(0,CValueTypeDemo::ThreadProc),new String("Yzl01"));
        ThreadPool::QueueUserWorkItem(
new WaitCallback(0,CValueTypeDemo::ThreadProc),new String("Yzl02"));
        ThreadPool::QueueUserWorkItem(
new WaitCallback(0,CValueTypeDemo::ThreadProc),new String("Yzl03"));
        Console::ReadLine();
}
 
__pin 关键字防止无用单元收集器移动对象同时也可以让C++编译器允许我们将其强制转换为检查内存所需的非托管指针.
编译运行:
E:/>cl CValueTypeDemo.cpp /clr
E:/>CValueTypeDemo
Object:Yzl01
Address 4be39ac:03000000  0807b979
Address 4be39b4:05000000  00000000
Object:Yzl02
Address 4be5144:04000000  0807b979
Address 4be514c:05000000  00000000
Object:Yzl03
Address 4be62bc:03000000  0807b979
Address 4be62c4:05000000  00000000
exit

测试表明数据并未同步.第一次封箱产生的对象是4be39ac,它的同步对象索引块为03000000,值为05000000.

如果我们需要同步访问一个值类型,那么可以使用typeof(v)获取同步对象.
 
示例 -- 采用typeof同步数据
 
using  System;
using  System.Threading;

public   class  TypeofDemo
{
    
public static void Main(string[] args)
    
{
        ThreadPool.QueueUserWorkItem(
new WaitCallback(ThreadProc),"Yzl01");
            ThreadPool.QueueUserWorkItem(
new WaitCallback(ThreadProc),"Yzl02");
            ThreadPool.QueueUserWorkItem(
new WaitCallback(ThreadProc),"Yzl03");
            Console.ReadLine();
    }


    
private static void ThreadProc(object state)
    
{
        Thread.Sleep(
500);
        Console.WriteLine(
"Object:{0},Current Thread:{1}",state,AppDomain.GetCurrentThreadId());
        
        
lock(typeof(int))
        
{
            x 
= AppDomain.GetCurrentThreadId();
            Console.WriteLine(
"x={0}",x);
        }

    }

    
    
private static int x = 3;
}

编译运行:
E:/>csc TypeofDemo.cs
E:/>TypeofDemo
Object:Yzl01,Current Thread:2416
x=2416
Object:Yzl02,Current Thread:2416
x=2416
Object:Yzl03,Current Thread:2404
x=2404
exit
E:/>
记住,typeof(v)对于所有的v实例总是返回相同的对象.我们测试一下:
//  TypeofDemo.cs
//  Author by Yzl

using  System;
using  System.Threading;

public   class  TypeofDemo
{
    
public static void Main(string[] args)
    
{
        ThreadPool.QueueUserWorkItem(
new WaitCallback(ThreadProc),1);
            ThreadPool.QueueUserWorkItem(
new WaitCallback(ThreadProc),2);
            ThreadPool.QueueUserWorkItem(
new WaitCallback(ThreadProc),3);
            Console.ReadLine();
    }


    
private static void ThreadProc(object state)
    
{
        
lock(((int)state).GetType())
        
{
            Thread.Sleep(
500);
            Console.WriteLine(
"Object:{0},Current Thread:{1}",state,AppDomain.GetCurrentThreadId());
            Thread.Sleep(
500);
            Console.WriteLine(
"Object:{0},Current Thread:{1}",state,AppDomain.GetCurrentThreadId());
        }

    }

}

运行如下:
E:/>csc TypeofDemo.cs
E:/>TypeofDemo
Object:1,Current Thread:1020
Object:1,Current Thread:1020
Object:2,Current Thread:2496
Object:2,Current Thread:2496
Object:3,Current Thread:1020
Object:3,Current Thread:1020
exit
很明显各个线程先后执行完毕.如果将lock语句改为lock(state)我们观察下又会是什么样的结果:
E:/>TypeofDemo
Object:1,Current Thread:2444
Object:1,Current Thread:2444
Object:2,Current Thread:2508
Object:3,Current Thread:2512
Object:2,Current Thread:2508
Object:3,Current Thread:2512
exit
线程执行并无顺序,2508号线程还没未执行完就被2512号线程抢去了.换句话说,这时的lock并没有起到同步对象的作用.
线程同步还涉及到死锁等现象,这里不再探讨.合理地应用锁才可能最大限度地预防数据破坏及产生死锁.
End.
--------------------------------------------------------------------------------
【版权声明】: 本文原创于厦门, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2007年03月02日 13:33:38

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值