`
wyf
  • 浏览: 437911 次
  • 性别: Icon_minigender_1
  • 来自: 唐山
社区版块
存档分类
最新评论

使用 ConcurrentBag 创建目标池

    博客分类:
  • C#
 
阅读更多

本示例演示如何使用并发包来实现对象池。 在需要某个类的多个实例并且创建或销毁该类的成本很高的情况下,对象池可以改进应用程序性能。 客户端程序请求新对象时,对象池先尝试提供一个已创建并返回到该池的对象。 仅在没有可用对象时,才会创建一个新对象。

ConcurrentBag<T> 用于存储对象,因为它支持快速插入和删除,特别是在同一线程既添加又删除项时。 本示例可进一步扩充为以包数据结构实现的 IProducerConsumerCollection<T> 为依据生成,就像 ConcurrentQueue<T> 和 ConcurrentStack<T> 一样。

using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;


namespace ObjectPoolExample
{
    public class ObjectPool<T>
    {
        private ConcurrentBag<T> _objects;
        private Func<T> _objectGenerator;

        public ObjectPool(Func<T> objectGenerator)
        {
            if (objectGenerator == null) throw new ArgumentNullException("objectGenerator");
            _objects = new ConcurrentBag<T>();
            _objectGenerator = objectGenerator;
        }

        public T GetObject()
        {
            T item;
            if (_objects.TryTake(out item)) return item;
            return _objectGenerator();
        }

        public void PutObject(T item)
        {
            _objects.Add(item);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            CancellationTokenSource cts = new CancellationTokenSource();

            // Create an opportunity for the user to cancel.
            Task.Run(() =>
            {
                if (Console.ReadKey().KeyChar == 'c' || Console.ReadKey().KeyChar == 'C')
                    cts.Cancel();
            });

            ObjectPool<MyClass> pool = new ObjectPool<MyClass>(() => new MyClass());

            // Create a high demand for MyClass objects.
            Parallel.For(0, 1000000, (i, loopState) =>
            {
                MyClass mc = pool.GetObject();
                Console.CursorLeft = 0;
                // This is the bottleneck in our application. All threads in this loop
                // must serialize their access to the static Console class.
                Console.WriteLine("{0:####.####}", mc.GetValue(i));

                pool.PutObject(mc);
                if (cts.Token.IsCancellationRequested)
                    loopState.Stop();

            });
            Console.WriteLine("Press the Enter key to exit.");
            Console.ReadLine();
            cts.Dispose();
        }

    }

    // A toy class that requires some resources to create.
    // You can experiment here to measure the performance of the
    // object pool vs. ordinary instantiation.
    class MyClass
    {
        public int[] Nums { get; set; }
        public double GetValue(long i)
        {
            return Math.Sqrt(Nums[i]);
        }
        public MyClass()
        {
            Nums = new int[1000000];
            Random rand = new Random();
            for (int i = 0; i < Nums.Length; i++)
                Nums[i] = rand.Next();
        }
    }
}

 

分享到:
评论

相关推荐

    Spring Boot如何使用HikariCP连接池详解

    HikariCP通过使用Javassist库进行字节码操作,提高了性能,并使用了如FastList和ConcurrentBag等特殊集合类,以优化并发处理和内存使用。 **一、HikariCP的引入** 要在Spring Boot项目中引入HikariCP,只需要添加`...

    C# 线程池的使用 高级应用

    总结,C#线程池的高级应用涉及到线程的创建、调度、监控以及与异步I/O的结合使用。通过合理利用线程池,开发者可以构建高效、稳定的多线程应用程序。在实际开发中,应结合项目需求和系统资源,灵活运用线程池的各种...

    .NET Core中Object Pool的多种用法详解

    除了使用`DefaultObjectPool`,还可以自定义对象池实现,如使用`ConcurrentBag`或`ConcurrentQueue`。这需要实现`IPool&lt;T&gt;`接口,包括`Get`、`Return`和`Clear`等方法。例如: ```csharp public class ...

    C# 线程使用总结

    本文将深入探讨C#线程的使用,包括创建线程、线程同步、线程通信以及如何管理和控制线程。 1. **线程创建** 在C#中,可以通过两种主要方式创建线程:使用`Thread`类或使用`Task`类。`Thread`类是最原始的方法,...

    多线程使用同一数组测试

    3. **线程池(ThreadPool)**:合理使用线程池,避免过度创建线程,减少并发冲突的可能性。 4. **信号量(Semaphore)**:使用`Semaphore`或`SemaphoreSlim`类限制同时访问数组的线程数量,实现资源的有限并发访问...

    c#官方线程安全集合源码

    `ConcurrentBag&lt;T&gt;`内部使用了一种称为"segmented bag"的数据结构,能够高效地处理并发插入和移除操作。 2. **ConcurrentQueue** `ConcurrentQueue&lt;T&gt;` 是线程安全的队列实现,遵循先进先出(FIFO)原则。在多线程...

    ParallelProgramsinNET4_CodingGuidelines

    例如,使用 `ConcurrentBag` 来存储并发生成的元素: ```csharp ConcurrentBag&lt;int&gt; bag = new ConcurrentBag(); Parallel.ForEach(numbers, number =&gt; { bag.Add(number * number); }); ``` #### 协调原语 协调...

    C#,多线程,搜索文件,查找文件,源代码

    在IT行业中,C#是一种广泛使用的编程语言,尤其在Windows平台的应用开发中。多线程技术是C#中一个核心的特性,它允许程序同时执行多个任务,提高系统的并发性和效率。本文将深入探讨C#中多线程的运用以及如何在多...

    C#多线程List的非线程安全性

    2. 使用线程安全的集合:.NET框架提供了线程安全的集合类,如ConcurrentBag、ConcurrentQueue和ConcurrentStack等,它们在内部实现了线程同步,可以安全地在多线程环境下使用。 3. 避免在多线程环境中直接修改List...

    asp.net多线程的TCP端口扫描程序的设计与实现(源代码+论文).zip

    可以使用ConcurrentCollections(如ConcurrentBag或ConcurrentDictionary)来安全地收集各线程的结果。 9. **论文撰写**:对于“源代码+论文”的部分,论文应涵盖设计思路、技术选型、实现过程、性能评估以及可能的...

    PerformanceCharacteristicsOfThreadSafeCollection

    本文将详细介绍这四种新的集合类型:`ConcurrentQueue&lt;T&gt;`、`ConcurrentStack&lt;T&gt;`、`ConcurrentBag&lt;T&gt;` 和 `ConcurrentDictionary, TValue&gt;`,以及它们的性能特点。 #### 新的线程安全集合类型 ##### 1. `...

    c# 文件多线程扫描,这次是真的,上次真是。。。汗。。。

    可以使用`ConcurrentBag`或`BlockingCollection`等线程安全的数据结构来收集扫描结果,避免同步冲突。 5. **异常处理**:线程间的异常处理需要特别注意,确保每个线程的异常都能被妥善处理。可以使用`try-catch`...

    日志,NLog日志扩展,大批量日志插入操作源代码

    2. **日志事件的缓存策略**:你可以使用线程安全的数据结构(如`ConcurrentQueue`或`ConcurrentBag`)来存储待处理的日志事件。同时,需要设定一个合适的批量大小和超时时间,以便平衡性能和内存使用。 3. **线程...

    多线程格式化程序

    6. **线程安全的数据结构**: 如果有多个线程共享数据,如格式化进度列表,确保使用线程安全的数据结构,如`ConcurrentBag`或`ConcurrentDictionary`,或者在访问共享数据时使用`synchronized`关键字。 7. **资源...

    c#线程参考手册

    - 使用System.Threading命名空间下的Thread类来创建线程。 - 通过传递一个委托给Thread类的构造函数来定义线程要执行的方法。 - 使用Thread.Start()方法来启动线程。 - 可以使用Thread构造函数中的...

    C#列表集合的测试用例

    5. **线程安全**:在多线程环境中,考虑使用`ConcurrentBag&lt;T&gt;`或`ConcurrentQueue&lt;T&gt;`等线程安全的集合,而非直接对`List&lt;T&gt;`进行并发操作。 6. **内存优化**:在性能敏感的应用中,可以考虑使用`LinkedList&lt;T&gt;`...

    ArrayList的线程安全测试

    例如,可以使用`ConcurrentBag&lt;T&gt;`替代ArrayList。 在给定的文件列表中,"ThreadSafe_ArrayList.csproj"可能是一个项目文件,包含实现线程安全ArrayList测试的代码。"Form1.cs"和"Form1.Designer.cs"通常用于...

    c#寻找局域网内的ip(源码)

    这可能涉及到线程安全的数据结构,如`ConcurrentBag`,或者使用`lock`关键字保护共享资源。 9. **性能优化**:在实际应用中,可能还需要考虑其他优化策略,比如使用缓存已知活跃的IP地址,或者定期更新IP列表而不是...

    C#dotNet4并行编程(英文版).zip

    此外,`Concurrent Collections`(如 `ConcurrentBag`、`ConcurrentDictionary` 和 `ConcurrentQueue`)是线程安全的数据结构,可简化多线程环境下的数据共享。 四、异常处理 并行编程中的异常处理比串行编程更为...

    C#与.NET+4高级程序设计+第5版

    这部分可能会讲解如何使用`Task`类、`Parallel`类和`async/await`关键字来创建异步操作,提高应用程序的性能和响应性。此外,还会涉及线程同步机制,如锁(`lock`关键字)、Monitor、Mutex、Semaphore等,以及并发...

Global site tag (gtag.js) - Google Analytics