C# 如何做到多线程阻塞后不等待直接放弃

比如C# 中的lock(){}代码,多线程调用时,有一个线程在使用了,其他线程就会等待。
但是我有一个需求,A、B、C 3个线程共同竞争一个函数Test(),谁先抢到归谁,其他2个线程发现已有线程在使用这个函数,直接放弃调用。
C#中有没有这种写法啊,多线程不等待直接放弃

用 Monitor:

using System;
using System.Threading;

class Program
{
    static object lockObject = new object();

    static void Main(string[] args)
    {
        Thread threadA = new Thread(Test);
        Thread threadB = new Thread(Test);
        Thread threadC = new Thread(Test);

        threadA.Start("A");
        threadB.Start("B");
        threadC.Start("C");

        threadA.Join();
        threadB.Join();
        threadC.Join();
    }

    static void Test(object threadName)
    {
        if (Monitor.TryEnter(lockObject))
        {
            try
            {
                Console.WriteLine($"Thread {threadName} acquired the lock.");
                // 执行需要互斥的代码
            }
            finally
            {
                Monitor.Exit(lockObject);
            }
        }
        else
        {
            Console.WriteLine($"Thread {threadName} skipped the call.");
        }
    }
}

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 以下回答由chatgpt基于相关博客总结生成:

    可以使用Monitor.TryEnter方法来实现多线程竞争函数调用,如果无法获取资源则直接放弃。

    具体步骤如下:

    Step 1: 创建一个共享资源对象,例如一个标志位来表示函数是否被占用。

    bool isTestRunning = false;
    

    Step 2: 在函数Test()开始的地方使用Monitor.TryEnter方法来竞争调用权。如果无法获取资源,则放弃调用。

    public void Test()
    {
        if (Monitor.TryEnter(isTestRunning))
        {
            try
            {
                // 执行函数的逻辑
            }
            finally
            {
                Monitor.Exit(isTestRunning);
            }
        }
        else
        {
            // 放弃调用该函数
            return;
        }
    }
    

    Step 3: 在多个线程中调用函数Test()。

    Thread threadA = new Thread(() => { Test(); });
    Thread threadB = new Thread(() => { Test(); });
    Thread threadC = new Thread(() => { Test(); });
    
    threadA.Start();
    threadB.Start();
    threadC.Start();
    
    threadA.Join();
    threadB.Join();
    threadC.Join();
    

    这样就可以实现多线程竞争函数调用,如果无法获取资源则直接放弃。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^