发新话题
打印

有趣的多线程编程(3)——线程内部是如何进行的?

有趣的多线程编程(3)——线程内部是如何进行的?

看一下以下两个例子的运行结果://TestThread.csusing System;
using System.Threading;

public class Test
{
    static int count=0;
   
    static void Main()
    {
        ThreadStart job = new ThreadStart(ThreadJob);
        Thread thread = new Thread(job);
        thread.Start();
        
        for (int i=0; i < 5; i  )
        {
            count  ;
        }
        
        thread.Join();
        Console.WriteLine ("Final count: {0}", count);
    }
   
    static void ThreadJob()
    {
        for (int i=0; i < 5; i  )
        {
            count  ;
        }
    }
}   

//InnerDataThread.cs
using System;
using System.Threading;

public class Test
{
    static int count=0;
   
    static void Main()
    {
        ThreadStart job = new ThreadStart(ThreadJob);
        Thread thread = new Thread(job);
        thread.Start();
        
        for (int i=0; i < 5; i  )
        {
            int tmp = count;
            Console.WriteLine ("Read count={0}", tmp);
            Thread.Sleep(50);
            tmp  ;
            Console.WriteLine ("Incremented tmp to {0}", tmp);
            Thread.Sleep(20);
            count = tmp;
            Console.WriteLine ("Written count={0}", tmp);
            Thread.Sleep(30);
        }
        
        thread.Join();
        Console.WriteLine ("Final count: {0}", count);
    }
   
    static void ThreadJob()
    {
        for (int i=0; i < 5; i  )
        {
            int tmp = count;
            Console.WriteLine ("\t\t\t\tRead count={0}", tmp);
            Thread.Sleep(20);
            tmp  ;
            Console.WriteLine ("\t\t\t\tIncremented tmp to {0}", tmp);
            Thread.Sleep(10);
            count = tmp;
            Console.WriteLine ("\t\t\t\tWritten count={0}", tmp);
            Thread.Sleep(40);
        }
    }
}
Read count=0
                                Read count=0
                                Incremented tmp to 1
                                Written count=1
Incremented tmp to 1
Written count=1
                                Read count=1
                                Incremented tmp to 2
Read count=1
                                Written count=2
                                Read count=2
Incremented tmp to 2
                                Incremented tmp to 3
Written count=2
                                Written count=3
Read count=3
                                Read count=3
Incremented tmp to 4
                                Incremented tmp to 4
                                Written count=4
Written count=4
                                Read count=4
Read count=4
                                Incremented tmp to 5
                                Written count=5
Incremented tmp to 5
Written count=5
Read count=5
Incremented tmp to 6
Written count=6
Final count: 6



再比较下面这个例子:
//使用Monitor.Enter/Exit
//MonitorThread.cs

using System;
using System.Threading;

public class Test
{
    static int count=0;
    static readonly object countLock = new object();
   
    static void Main()
    {
        ThreadStart job = new ThreadStart(ThreadJob);
        Thread thread = new Thread(job);
        thread.Start();
        
        for (int i=0; i < 5; i  )
        {
            Monitor.Enter(countLock);
            int tmp = count;
            Console.WriteLine ("Read count={0}", tmp);
            Thread.Sleep(50);
            tmp  ;
            Console.WriteLine ("Incremented tmp to {0}", tmp);
            Thread.Sleep(20);
            count = tmp;
            Console.WriteLine ("Written count={0}", tmp);
            Monitor.Exit(countLock);
            Thread.Sleep(30);
        }
        
        thread.Join();
        Console.WriteLine ("Final count: {0}", count);
    }
   
    static void ThreadJob()
    {
        for (int i=0; i < 5; i  )
        {
            Monitor.Enter(countLock);
            int tmp = count;
            Console.WriteLine ("\t\t\t\tRead count={0}", tmp);
            Thread.Sleep(20);
            tmp  ;
            Console.WriteLine ("\t\t\t\tIncremented tmp to {0}", tmp);
            Thread.Sleep(10);
            count = tmp;
            Console.WriteLine ("\t\t\t\tWritten count={0}", tmp);
            Monitor.Exit(countLock);
            Thread.Sleep(40);
        }
    }
}

结果与上例InnerDataThread.cs是不一样的,原因就在于Monitor的使用了。
Read count=0
Incremented tmp to 1
Written count=1
                                Read count=1
                                Incremented tmp to 2
                                Written count=2
Read count=2
Incremented tmp to 3
Written count=3
                                Read count=3
                                Incremented tmp to 4
                                Written count=4
Read count=4
Incremented tmp to 5
Written count=5
                                Read count=5
                                Incremented tmp to 6
                                Written count=6
Read count=6
Incremented tmp to 7
Written count=7
                                Read count=7
                                Incremented tmp to 8
                                Written count=8
Read count=8
Incremented tmp to 9
Written count=9
                                Read count=9
                                Incremented tmp to 10
                                Written count=10
Final count: 10


下面使用lock来锁定线程:
// LockThread.cs
using System;
using System.Threading;

public class Test
{
    static int count=0;
    static readonly object countLock = new object();
   
    static void Main()
    {
        ThreadStart job = new ThreadStart(ThreadJob);
        Thread thread = new Thread(job);
        thread.Start();
        
        for (int i=0; i < 5; i  )
        {
            lock (countLock)
            {
                int tmp = count;
                Console.WriteLine ("Read count={0}", tmp);
                Thread.Sleep(50);
                tmp  ;
                Console.WriteLine ("Incremented tmp to {0}", tmp);
                Thread.Sleep(20);
                count = tmp;
                Console.WriteLine ("Written count={0}", tmp);
            }
            Thread.Sleep(30);
        }
        
        thread.Join();
        Console.WriteLine ("Final count: {0}", count);
    }
   
    static void ThreadJob()
    {
        for (int i=0; i < 5; i  )
        {
            lock (countLock)
            {
                int tmp = count;
                Console.WriteLine ("\t\t\t\tRead count={0}", tmp);
                Thread.Sleep(20);
                tmp  ;
                Console.WriteLine ("\t\t\t\tIncremented tmp to {0}", tmp);
                if (count < 100)
                    throw new Exception();
                Thread.Sleep(10);
                count = tmp;
                Console.WriteLine ("\t\t\t\tWritten count={0}", tmp);
            }
            Thread.Sleep(40);
        }
    }
}

结果如何?与MonitorThread.cs比较一下,再想想看。

TOP

发新话题