c#基础知识篇-Monitor

作用

提供同步访问对象的机制,实现线程同步。

命名空间&程序集

命名空间:System.Threading
程序集:System.Threading.dll

属性

LockContentionCount 获取尝试锁定监视器时出现争用的次数。

 

 

方法

Enter(Object)

在指定对象上获取排他锁。

Enter(Object, Boolean)

获取指定对象上的排他锁,并自动设置一个值,指示是否获取了该锁。

Exit(Object)

释放指定对象上的排他锁。

IsEntered(Object)

确定当前线程是否保留指定对象上的锁。

Pulse(Object)

通知等待队列中的线程锁定对象状态的更改。

PulseAll(Object)

通知所有的等待线程对象状态的更改。

TryEnter(Object)

尝试获取指定对象的排他锁。

TryEnter(Object, Boolean)

尝试获取指定对象上的排他锁,并自动设置一个值,指示是否获取了该锁。

TryEnter(Object, Int32)

在指定的毫秒数内尝试获取指定对象上的排他锁。

TryEnter(Object, Int32, Boolean)

在指定的毫秒数内尝试获取指定对象上的排他锁,并自动设置一个值,指示是否获取了该锁。

TryEnter(Object, TimeSpan)

在指定的时间内尝试获取指定对象上的排他锁。

TryEnter(Object, TimeSpan, Boolean)

在指定的一段时间内尝试获取指定对象上的排他锁,并自动设置一个值,指示是否获得了该锁。

Wait(Object)

释放对象上的锁并阻止当前线程,直到它重新获取该锁。

Wait(Object, Int32)

释放对象上的锁并阻止当前线程,直到它重新获取该锁。 如果已用指定的超时时间间隔,则线程进入就绪队列。

Wait(Object, Int32, Boolean)

释放对象上的锁并阻止当前线程,直到它重新获取该锁。 如果已用指定的超时时间间隔,则线程进入就绪队列。 此方法还指定是否在等待之前退出上下文的同步域(如果在同步上下文中)然后重新获取该同步域。

Wait(Object, TimeSpan)

释放对象上的锁并阻止当前线程,直到它重新获取该锁。 如果已用指定的超时时间间隔,则线程进入就绪队列。

Wait(Object, TimeSpan, Boolean)

释放对象上的锁并阻止当前线程,直到它重新获取该锁。 如果已用指定的超时时间间隔,则线程进入就绪队列。 可以在等待之前退出同步上下文的同步域,随后重新获取该域。

 

 

注意事项

1. Enter和Exit是常用的两个方法,使用过程中须注意,为了防止获取锁之后因程序异常导致锁无法释放的情况,需要在try-catch之后的finally结构体中释放锁(Monitor.Exit())。

2. Monitor和TryEnter区别:TryEnter不会像Enter那样阻塞执行,如果线程成功进入关键区域会返回true

3. 为了避免死锁的发生,尽量用TryEnter(Object)或TryEnter()方法尝试获取一个对象上的显示锁。

代码

using System;
using System.IO;
using System.Threading;

namespace MonitorDemo
{
    public class Program
    {
        private static readonly object objlock = new object();
        private static int number = 0;
        static void Main(string[] args)
        {
            
            string path = AppDomain.CurrentDomain.BaseDirectory + "\\monitor.txt";
            File.WriteAllText(path, "");

            for (int i = 0; i < 100; i++)
            {
                new Thread(m =>
                {
                    if (Monitor.TryEnter(objlock))
                    {
                        try
                        {
                            WriteContent(path);
                        }
                        catch (Exception)
                        {

                            throw;
                        }
                        finally
                        {
                            Monitor.Exit(objlock);
                        }
                    }

                }).Start();
            }
        }

        public static void WriteContent(string path)
        {
            string content = "编号 " + number + " : " + DateTime.Now.ToShortTimeString() + "\r\n";
            File.AppendAllText(path, content);
            number++;
        }
    }
}

 

posted @ 2023-07-09 09:08  相遇就是有缘  阅读(95)  评论(0)    收藏  举报