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 @   相遇就是有缘  阅读(68)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
历史上的今天:
2022-07-09 生命周期、钩子函数
  1. 1 我记得 赵雷
  2. 2 北京东路的日子 汪源
  3. 3 把回忆拼好给你 王贰浪
北京东路的日子 - 汪源
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

Not available

点击右上角即可分享
微信分享提示