C#中的线程同步及线程用到的锁对象

 

线程同步及线程用到的锁对象

    如果程序涉及到多个线程协同完成某项任务,那么你将会面对线程同步的问题。.Net为这类为题提供了很好的解决方案,我们只需要书写少量的代码就能避免线程出现死锁。

线程同步

辅助类   
 class ThreadSync

    {

        public long data1;

        public long data2;

 

        public void Increase()

        {

            data2++;

        }

}

 

    class AlgorithmicTimer

    {

        public DateTime startTime { get; set; }

        public DateTime endTime { get; set; }

 

        public void Analyse()

        {

            Console.WriteLine(

string.Format("当前程序共运行了:{0}秒"

, (endTime - startTime).TotalSeconds));

        }

 

 

    }

}


 

调用代码
ThreadSync myThreadSync = new ThreadSync();

AlgorithmicTimer timer = new AlgorithmicTimer();

            

    timer.startTime = DateTime.Now;

    for (int i = 0; i < 100000000; i++)

    {

        myThreadSync.Increase();

}

 

    Console.WriteLine(myThreadSync.data2);

    timer.endTime = DateTime.Now;

    timer.Analyse();

            

    myThreadSync.data2 = 0;

    timer.startTime = DateTime.Now;

    Parallel.For(0, 100000000, (index) =>

    {

        lock (myThreadSync)  //不加上Lock得到的结果不正确

        {

            myThreadSync.Increase();

        }

});

 

    Console.WriteLine(myThreadSync.data2);

    timer.endTime = DateTime.Now;

    timer.Analyse();


 

执行结果

 100000000

当前程序共运行了:1.1740671秒

100000000

当前程序共运行了:11.4436546秒

 

 

PV信号量操作

 

   //Semaphore 信号量对象,PV 操作

    int threadCount = 6;

    int semaphoreCount = 4;

    var semaphore = new SemaphoreSlim(semaphoreCount, semaphoreCount);

    var threads = new Thread[threadCount];

 

    for (int i = 0; i < threadCount; i++)

    {

        threads[i] = new Thread(mysemaphore.ThreadMain);

        threads[i].Start(semaphore);

    }

 

    for (int i = 0; i < threadCount; i++)

    {

        threads[i].Join();

    }

    Console.WriteLine("All threads finished!");

 


 

Mysemaphore类型

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

using System.Threading;

using System.Threading.Tasks;

using System.Diagnostics;

 

namespace chapter20

{

    class mysemaphore

    {

        public static  void ThreadMain(object o)

        {

            SemaphoreSlim semaphore = o as SemaphoreSlim;

            Trace.Assert(semaphore != null, "o must be a Semaphore type");

            bool isCompleted = false;

            while (!isCompleted)

            {

                if (semaphore.Wait(600))

                {

                    try

                    {

                        Console.WriteLine("Thread {0} locks the semaphore

,Current PV:{1}"

, new object[]{Thread.CurrentThread.ManagedThreadId,semaphore.CurrentCount});

                       

                        Thread.Sleep(2000);

                    }

                    finally

                    {

                        semaphore.Release();

                        Console.WriteLine("Thread {0} release the semaphore,Current PV:{1}", new object[]{Thread.CurrentThread.ManagedThreadId,semaphore.CurrentCount});

                     

                        isCompleted = true;

                    }

                }

                else

                {

                    Console.WriteLine("Timeout for thread {0},wait again", Thread.CurrentThread.ManagedThreadId);

                }

            }

        }

    }

}


 

执行结果:

 Thread 9 locks the semaphore,Current PV:3

Thread 10 locks the semaphore,Current PV:2

Thread 11 locks the semaphore,Current PV:1

Thread 12 locks the semaphore,Current PV:0

Timeout for thread 13,wait again

Timeout for thread 14,wait again

Timeout for thread 13,wait again

Timeout for thread 14,wait again

Thread 9 release the semaphore,Current PV:1

Thread 13 locks the semaphore,Current PV:0

Thread 11 release the semaphore,Current PV:2

Timeout for thread 14,wait again

Thread 10 release the semaphore,Current PV:1

Thread 14 locks the semaphore,Current PV:2

Thread 12 release the semaphore,Current PV:3

Thread 13 release the semaphore,Current PV:3

Thread 14 release the semaphore,Current PV:4

All threads finished!

 

 

Event类

    解决资源分配问题,当程序释放资源时改变该事件的状态。通知其他程序它释放了资源。

辅助类

   

class Calculator

    {

        private ManualResetEventSlim mEvent;

        public int Result { get; private set; }

        public Calculator(ManualResetEventSlim ev)

        {

            this.mEvent = ev;

        }

 

        public void Calculation(object obj)

        {

            Tuple<int, int> data = obj as Tuple<int, int>;

            Console.WriteLine("Task {0} starts calculation"

, Task.CurrentId);

            Thread.Sleep(new Random().Next(3000));

            Result = data.Item1 + data.Item2;

 

            Console.WriteLine("Task {0} is ready", Task.CurrentId);

            mEvent.Set();

        }

}

 


 

 

调用代码:

   

 //Event 类

    int taskCount = 4;

    var mEvents = new ManualResetEventSlim[taskCount];

    var waitHandles = new WaitHandle[taskCount];

    var calcs = new Calculator[taskCount];

 

    TaskFactory taskFactory = new TaskFactory();

    for (int i = 0; i < taskCount; i++)

    {

        mEvents[i] = new ManualResetEventSlim(false);

        waitHandles[i] = mEvents[i].WaitHandle;

        calcs[i] = new Calculator(mEvents[i]);

 

        taskFactory.StartNew(calcs[i].Calculation, Tuple.Create(i + 1, i + 3));

 

    }

 

    for (int i = 0; i < taskCount; i++)

    {

        int index = WaitHandle.WaitAny(waitHandles);

        if (index == WaitHandle.WaitTimeout)

        {

            Console.WriteLine("Timeout!!");

        }

        else

        {

            mEvents[index].Reset();

            Console.WriteLine("finished task for {0},result:{1}", index, calcs[index].Result);

        }

 

    }

 


 

执行结果:

 Task 1 starts calculation

Task 3 starts calculation

Task 2 starts calculation

Task 4 starts calculation

Task 2 is ready

Task 3 is ready

Task 4 is ready

finished task for 1,result:6

finished task for 2,result:8

finished task for 3,result:10

Task 1 is ready

finished task for 0,result:4

 

 

 

ReadWriterLockSlim(同步资源的读写)

    呵呵,额对这个东西的产生表示很无解。

  

  class MyReadWriterLockSlim

    {

        private static List<int> items = new List<int>() { 0, 1, 2, 3, 4, 5 };

        private static ReaderWriterLockSlim rwl = new

              ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);

 

       public static void ReaderMethod(object reader)

        {

            try

            {

                rwl.EnterReadLock();

 

                for (int i = 0; i < items.Count; i++)

                {

                    Console.WriteLine("reader {0}, loop: {1}, item: {2}",

                          reader, i, items[i]);

                    Thread.Sleep(40);

                }

            }

            finally

            {

                rwl.ExitReadLock();

            }

        }

 

       public static void WriterMethod(object writer)

        {

            try

            {

                while (!rwl.TryEnterWriteLock(50))

                {

                    Console.WriteLine("Writer {0} waiting for the write lock",

                          writer);

                    Console.WriteLine("current reader count: {0}",

                          rwl.CurrentReadCount);

                }

                Console.WriteLine("Writer {0} acquired the lock", writer);

                for (int i = 0; i < items.Count; i++)

                {

                    items[i]++;

                    Thread.Sleep(50);

                }

                Console.WriteLine("Writer {0} finished", writer);

            }

            finally

            {

                rwl.ExitWriteLock();

            }

        }

 

       public static void Go()

        {

            var taskFactory = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.None);

            var tasks = new Task[6];

            tasks[0] = taskFactory.StartNew(WriterMethod, 1);

            tasks[1] = taskFactory.StartNew(ReaderMethod, 1);

            tasks[2] = taskFactory.StartNew(ReaderMethod, 2);

            tasks[3] = taskFactory.StartNew(WriterMethod, 2);

            tasks[4] = taskFactory.StartNew(ReaderMethod, 3);

            tasks[5] = taskFactory.StartNew(ReaderMethod, 4);

 

            for (int i = 0; i < 6; i++)

            {

                tasks[i].Wait();

            }

        }

    }

 


 

执行结果:

 reader 1, loop: 0, item: 0

reader 1, loop: 1, item: 1

reader 3, loop: 0, item: 0

Writer 1 waiting for the write lock

current reader count: 3

reader 4, loop: 0, item: 0

Writer 2 waiting for the write lock

reader 1, loop: 2, item: 2

reader 3, loop: 1, item: 1

current reader count: 3

reader 4, loop: 1, item: 1

reader 3, loop: 2, item: 2

reader 1, loop: 3, item: 3

reader 4, loop: 2, item: 2

Writer 1 waiting for the write lock

reader 3, loop: 3, item: 3

current reader count: 3

Writer 2 waiting for the write lock

reader 1, loop: 4, item: 4

reader 3, loop: 4, item: 4

reader 4, loop: 3, item: 3

current reader count: 3

Writer 1 waiting for the write lock

current reader count: 3

reader 3, loop: 5, item: 5

reader 1, loop: 5, item: 5

reader 4, loop: 4, item: 4

reader 4, loop: 5, item: 5

Writer 2 waiting for the write lock

Writer 1 waiting for the write lock

current reader count: 1

reader 2, loop: 0, item: 0

current reader count: 1

reader 2, loop: 1, item: 1

Writer 2 waiting for the write lock

Writer 1 waiting for the write lock

reader 2, loop: 2, item: 2

current reader count: 1

current reader count: 1

reader 2, loop: 3, item: 3

Writer 1 waiting for the write lock

Writer 2 waiting for the write lock

reader 2, loop: 4, item: 4

current reader count: 1

current reader count: 1

reader 2, loop: 5, item: 5

Writer 2 waiting for the write lock

Writer 1 waiting for the write lock

current reader count: 0

current reader count: 0

Writer 1 acquired the lock

Writer 2 waiting for the write lock

current reader count: 0

Writer 2 waiting for the write lock

current reader count: 0

Writer 2 waiting for the write lock

current reader count: 0

Writer 1 finished

Writer 2 acquired the lock

Writer 2 finished

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值