首页 > 编程语言 >C#实现JAVA的Synchronized

C#实现JAVA的Synchronized

时间:2025-01-20 15:58:59浏览次数:3  
标签:JAVA Synchronized Thread C# lock counter static IncrementCounter new

在JAVA中,用synchronized关键字用于确保多个线程不会同时执行某个方法或代码块,从而防止并发问题,C#中有多中方法来处理这种情况。

Lock语句

lock语句是最常用的同步机制,类似于JAVA的synchronized。他使用一个对象作为锁,确保同一个时间只有一个线程可以进入被锁定的代码块。示例如下。
using System;
using System.Threading;

class Program
{
    private static readonly object _lock = new object();
    private static int _counter = 0;

    static void Main()
    {
        Thread thread1 = new Thread(IncrementCounter);
        Thread thread2 = new Thread(IncrementCounter);

        thread1.Start();
        thread2.Start();

        thread1.Join();
        thread2.Join();

        Console.WriteLine($"Final counter value: {_counter}");
    }

    static void IncrementCounter()
    {
        for (int i = 0; i < 1000; i++)
        {
            lock (_lock)
            {
                _counter++;
            }
        }
    }
}

Monitor类

monitor提供了更细粒度的控制,允许手动进入临界区。lock语句实际是monitor的一个简化版本。monitor示例如下。

using System;
using System.Threading;
class Program
{
    private static readonly object _lock = new object();
    private static int _counter = 0;

    static void Main()
    {
        Thread thread1 = new Thread(IncrementCounter);
        Thread thread2 = new Thread(IncrementCounter);

        thread1.Start();
        thread2.Start();

        thread1.Join();
        thread2.Join();

        Console.WriteLine($"Final counter value: {_counter}");
    }

    static void IncrementCounter()
    {
        for (int i = 0; i < 1000; i++)
        {
            Monitor.Enter(_lock);
            try
            {
                _counter++;
            }
            finally
            {
                Monitor.Exit(_lock);
            }
        }
    }
}

Mutex类

Mutex类是一个互斥量类,是一个更重量级的一个同步机制,适用于跨进程的同步,和lock和monitor不同,mutex可以在不同进程之中共享。示例如下。

using System;
using System.Threading;

class Program
{
   private static Mutex _mutex = new Mutex();

   static void Main()
   {
       Thread thread1 = new Thread(IncrementCounter);
       Thread thread2 = new Thread(IncrementCounter);

       thread1.Start();
       thread2.Start();

       thread1.Join();
       thread2.Join();

       Console.WriteLine($"Final counter value: {_counter}");
   }

   private static int _counter = 0;

   static void IncrementCounter()
   {
       for (int i = 0; i < 1000; i++)
       {
           _mutex.WaitOne(); // 获取互斥量
           try
           {
               _counter++;
           }
           finally
           {
               _mutex.ReleaseMutex(); // 释放互斥量
           }
       }
   }
}

ReadWriterLockSlim

ReadWriterLockSlim提供读写锁功能,允许多个线程同时读资源,但是写入资源的时候,只允许一个线程访问,如果是在读多写入写入少的场景下是非常有用的。示例如下。

using System;
using System.Threading;

class Program
{
   private static ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
   private static int _counter = 0;

   static void Main()
   {
       Thread readerThread = new Thread(ReadCounter);
       Thread writerThread = new Thread(IncrementCounter);

       readerThread.Start();
       writerThread.Start();

       readerThread.Join();
       writerThread.Join();

       Console.WriteLine($"Final counter value: {_counter}");
   }

   static void ReadCounter()
   {
       for (int i = 0; i < 1000; i++)
       {
           _lock.EnterReadLock();
           try
           {
               Console.WriteLine($"Reading counter: {_counter}");
           }
           finally
           {
               _lock.ExitReadLock();
           }
       }
   }

   static void IncrementCounter()
   {
       for (int i = 0; i < 1000; i++)
       {
           _lock.EnterWriteLock();
           try
           {
               _counter++;
           }
           finally
           {
               _lock.ExitWriteLock();
           }
       }
   }
}

Semaphore ,SemaphoreSlim

Semaphore 和 SemaphoreSlim 允许多个线程同时访问资源,但限制了同时访问的最大线程数。SemaphoreSlim 是 Semaphore 的轻量级版本,适合单进程内的同步。示例如下。

using System;
using System.Threading;

class Program
{
   private static SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1); // 允许最多1个线程同时访问
   private static int _counter = 0;

   static void Main()
   {
       Thread thread1 = new Thread(IncrementCounter);
       Thread thread2 = new Thread(IncrementCounter);

       thread1.Start();
       thread2.Start();

       thread1.Join();
       thread2.Join();

       Console.WriteLine($"Final counter value: {_counter}");
   }

   static void IncrementCounter()
   {
       for (int i = 0; i < 1000; i++)
       {
           _semaphore.Wait(); // 等待进入临界区
           try
           {
               _counter++;
           }
           finally
           {
               _semaphore.Release(); // 释放临界区
           }
       }
   }
}

async,wait,semahporeSlim结合使用

如果场景有异步编程中进行同步操作,可以用以上三者结合,实现同步非阻塞的场景。示例如下。

using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
   private static SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1); // 允许最多1个线程同时访问
    private static int _counter = 0;

    static async Task Main()
    {
        Task task1 = IncrementCounterAsync();
        Task task2 = IncrementCounterAsync();

        await Task.WhenAll(task1, task2);

        Console.WriteLine($"Final counter value: {_counter}");
    }

    static async Task IncrementCounterAsync()
    {
        for (int i = 0; i < 1000; i++)
        {
            await _semaphore.WaitAsync(); // 等待进入临界区
            try
            {
                _counter++;
            }
            finally
            {
                _semaphore.Release(); // 释放临界区
            }
        }
    }
}

Interlocked

interlocked提供了一下原子操作,适用于一些简单的计数器,增量,减量的操作。比Lock还高效,原因在于他不需要创建和管理锁对象。

using System;
using System.Threading;

class Program
{
   private static int _counter = 0;

   static void Main()
   {
       Thread thread1 = new Thread(IncrementCounter);
       Thread thread2 = new Thread(IncrementCounter);

       thread1.Start();
       thread2.Start();

       thread1.Join();
       thread2.Join();

       Console.WriteLine($"Final counter value: {_counter}");
   }

   static void IncrementCounter()
   {
       for (int i = 0; i < 1000; i++)
       {
           Interlocked.Increment(ref _counter);
       }
   }
}

总结

lock:最常用的方式,简单易用,适用于大多数场景。
Monitor:提供了更细粒度的控制,适合需要手动管理锁的情况。
Mutex:适用于跨进程的同步。
Semaphore 和 SemaphoreSlim:允许多个线程同时访问资源,适合限制并发访问数量的场景。
ReaderWriterLockSlim:适用于读多写少的场景,允许多个线程同时读取资源。
Interlocked:提供了高效的原子操作,适合简单的计数器或增量操作。
根据你的具体需求选择合适的同步机制。如果你只是需要简单的线程安全,lock 或 Interlocked 通常是最佳选择。如果你需要更复杂的同步逻辑,可以考虑使用 Monitor、Mutex 或 ReaderWriterLockSlim。

标签:JAVA,Synchronized,Thread,C#,lock,counter,static,IncrementCounter,new
From: https://blog.csdn.net/qq_41435130/article/details/145262914

相关文章

  • 互联网Java架构师
    目录内容目录下载入口内容目录├─01、性能调优专题-JVM》│    01、性能调优专题-JVM》01、1-01、JVM类加载运行全过程梳理.mp4│    01、性能调优专题-JVM》02、1-02、java.exe运行一个类时JVMHotspot底层做了些什么.mp4│    01、性能调优专......
  • oracle设置数据库表空间自动扩展时注意事项
    在设置数据库表空间自动扩展时,需要注意以下几个关键事项,以确保数据库的稳定性和性能:确保足够的可用空间在启用表空间自动扩展之前,必须确保磁盘上有足够的可用空间来容纳扩展后的数据文件。--磁盘组空间占用百分比查询SELECTGROUP_NUMBER,NAME,TYPE,STATE,TOTAL_MB/1......
  • Go语言【Gin框架】:JSON、AsciiJSON、PureJSON和SecureJSON的区别
    在Go语言中,JSON、AsciiJSON、PureJSON和SecureJSON是Gin框架用于发送JSON响应的方法。1.c.JSON功能:将提供的数据序列化为标准的JSON格式,并将其作为HTTP响应发送给客户端。特点:支持Unicode字符,无需将非ASCII字符转义。某些字符(如<、>和&)会被自动转义为相应的Unicode......
  • C语言逆序操作数组和引用传递参数
    ////main.c//Test_C////Createdbystevexiaohuzhaoon2025/1/20.//#include<stdio.h>//C语言指针传递参数(引用传递)voidswap(int*px,int*py){intt=*px;*px=*py;*py=t;}voidtest(intn){intx=1;for(inti......
  • 基于java+springboot的网络选课管理系统
    一、系统概述“基于Java+SpringBoot的网络选课管理系统”是一个利用Java编程语言和SpringBoot框架开发的综合性平台,旨在为学校提供一个方便、高效、灵活的课程选择管理解决方案。二、功能特点用户管理:系统可区分不同角色,如学生、教师和管理员。学生可注册登录......
  • leetcode349-两个数组的交集
    leetcode349实现利用哈希set进行去重,然后循环nums2,如果nums2中的元素是在去重后的num1中出现过的,就存放在set2中,因为最后要返回的是不重复的数组,所以先放在set2,让其进行去重,最后把set2转为数组方法1varintersection=function(nums1,nums2){constset1=[........
  • 中国移动魔百盒CM311-1e(s)_S905L3SB芯片_2+16_安卓9_线刷固件包
    中国移动魔百盒CM311-1e(s)_S905L3SB芯片_2+16_安卓9_线刷固件包 线刷方法:(新手参考借鉴一下)1、准备好一根双公头USB线刷刷机线,长度30-50CM长度最佳,同时准备一台电脑,拆开盒子;2、电脑上安装好刷机工具AmlogicUSBBurningTool软件→打开软件→文件→导入烧录包→把......
  • TCP 和 UDP
    目录运输层概述TCP和UDP前置知识套接字套接字类型套接字处理过程IP端口号确定端口号多路复用和多路分解无连接的多路复用和多路分解面向连接的多路复用与多路分解UDPUDP特点UDP报文结构TCPTCP报文段结构序号、确认号实现传输可靠性累积确认传输控制利用窗口控制提高速度窗口......
  • 怎样用纯CSS实现禁止鼠标点击事件?
    在纯CSS中,没有直接的方法来禁止鼠标点击事件。CSS主要用于描述文档的样式,而不是控制其行为。点击事件等交互行为通常是通过JavaScript来处理的。然而,你可以使用CSS的pointer-events属性来阻止鼠标事件触发元素的默认行为。将pointer-events设置为none将使元素不再响应鼠标事件,例......
  • C语言实现顺序存储线性表
    ////Createdbystevexiaohuzhaoon2025/1/20.///****线性表的顺序存储结构实现*特点:逻辑上相邻的元素,物理上也相邻**/#include<stdio.h>#include<stdlib.h>#defineMAXSIZE100//定义线性表的最大长度//1.定义图书结构体Booktypedefstr......