代码就支持了多线程并发

100行代码就支持了多线程并发,批量写入日志

一,您选择用什么样的日志组件

日志组件,不得不提大名鼎鼎的Log4Net。比较常用的还有 Enterprise Library Logging,ServiceStack Logging。当然您还可以补充,我就只用过这几款。

上边提到的3款日志组件,都要在.config里加代码,特别是Log4Net,还要把SQL写在配置里。我就是仅仅只写个日志,还要配置这么多信息,让人略有不爽。

所以在很长一段时间里,我用下边这个方法写日志:

 

这个方法足够的简单,核心代码就只有那么5,6行,还包含容错机制。我就喜欢用这种简单的代码来处理简单的事。

二,多线程下引爆了问题

在多线程的情况下,比如100个线程同时需要写日志,上边提到的这个方法就力不从新了。

一个线程访问日志资源,另一个线程再去访问的时候,就会出现异常。

方法一:

    public static Object _processLock = new Object();

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        lock (_processLock)
        {

        }
    }

方法二:

    public static Object _processLock = new Object();

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        Monitor.Enter(_processLock);
        Monitor.Exit(_processLock);
    }

这样,你不得不承认,我已经解决了多线程的问题。

但是有瓶颈,这些需要写日志的线程,必须要等前一个释放了锁资源,后一个线程才能访问的情况。

三,重新设计日志组件

先看图,再说一下我的思路:

1,不管有多少线程同时需要写日志,我都用一个临时队列来存放这些日志信息。

2,再启用一个Task任务把队列的日志批量存放到.log文件里。

3,附加一个小功能,每个日志存储的大小限制,当日志太大了,查看打开的时候比较慢。

四,具体的代码实现

1,在多线程的情况下,我们首先把日志压到Queue队列里

    static ConcurrentQueue<Tuple<string, string>> logQueue = new ConcurrentQueue<Tuple<string, string>>();

在这儿,我为什么选用 ConcurrentQueue  而不是  Queue  。因为ConcurrentQueue  表示线程安全的先进先出 (FIFO) 集合。

当然你一定要用Queue也是可以的,但是要自己去实现锁机制,何必自找麻烦呢?

2,把日志队列里的数据,批量持久化到.log文件里

这个问题,让我很头大。我最开始的方法是:

持久化日志方法一:

a,申明一个Task任务,当我Task任务没有实现化时,先实例化,然后再进行持久化日志写入。

b,当我的Task任务,已经实例化了,并且是处于 IsCompleted 状态,我重新实例化Task,再进行持久化日志的写入。

    static Task writeTask = default(Task);

 

异常信息:

理论是那么的美好,但是现实是那么残酷,当我跑单元测试的时候,一段时间后总是抛出如下错误。如果是有那位朋友知道其原因,把这个问题解决就完美了。

但是我不能因为这一个异常,导致我这个组件写不下去吧!活人不能被一泡尿给憋死。

追加:完整代码如下:

 

持久化日志方法二:

我采用了另外一种方法,在Task任务里我用信号量的方式来解决了些问题,完整代码如下:

static AutoResetEvent pause = new AutoResetEvent(false);

信号量法:

 

持久化日志方法三:

如果你感觉写一个日志类还用什么信号量这些技术,太复杂了,那也可以用最简单的方式,定时器来解决。

有同学一听定时器,就默默的笑了,但是这儿的坑也很深,首先了解一下这几个定时器的使用场合,再用不迟!

System.Windows.Threading.DispatcherTimer

System.Windows.Forms.Timer

System.Timers.Timer

System.Threading.Timer

定时器法:

 

五,结语

重新设计的日志组件,思路还是非常清晰的。只是在持久化日志时遇上了问题了。

持久化日志方法一,其实是很完美的解决方法,但是在高并发的时候,总是抛出异常,找不出原因。

持久化日志方法二,是我目前采用的方法,能够有效的解决问题。

持久化日志方法三,采用定时器解决,也是可行的。只是代码看起来很别扭。

欢迎大家热烈讨论,看有没有更好的解决方案。

阿里云客户端的实现(支持文件分块,断点续传,进度,速度,倒计时显示)

淘宝刷单软件(刷单工具)程序实现

时间: 2024-08-07 12:29:24

代码就支持了多线程并发的相关文章

php如何支持实现多线程并发

<?php if(function_exists('date_default_timezone_set')) { date_default_timezone_set('PRC'); } function a() { $time = time(); sleep(3); $fp = fopen('result_a'.$time.'.log', 'w'); fputs($fp, 'Set in ' . Date('h:i:s', time()) . (double)microtime() . "

C# 防止同时调用=========使用读写锁三行代码简单解决多线程并发的问题

http://www.jb51.net/article/99718.htm 本文主要介绍了C#使用读写锁三行代码简单解决多线程并发写入文件时提示"文件正在由另一进程使用,因此该进程无法访问此文件"的问题.需要的朋友可以参考借鉴 在开发程序的过程中,难免少不了写入错误日志这个关键功能.实现这个功能,可以选择使用第三方日志插件,也可以选择使用数据库,还可以自己写个简单的方法把错误信息记录到日志文件. 选择最后一种方法实现的时候,若对文件操作与线程同步不熟悉,问题就有可能出现了,因为同一个文

Cocos2d-x优化中多线程并发访问

多线程并发访问在Cocos2d-x引擎中用的不是很多,这主要是因为中整个结构设计没有采用多线程.源自于Objective-C的Ref对象,需要使用AutoreleasePool进行内存管理,AutoreleasePool是非线程安全的,所有不推荐在子多线程中调用Ref对象的retain(). release()和autorelease()等函数.另外,OpenGL上下文对象也是不支持线程安全的.但是有的时候我们需要异步加载一些资源,例如:加载图片纹理.声音的预处理和网络请求数据等.如果是异步加载

解决多线程并发问题

1.文件锁 如果对该表的更新或插入的操作,都会经过一个统一的文件,这种方式是可以解决的多进程并发的问题: 实现方式如下: public static function cbInventoryReserve() { $LOCK_FILE_PATH = $_SERVER['DOCUMENT_ROOT']."wmsinventoryapi/inventory/InventoryReserve.php"; $fp = fopen( $LOCK_FILE_PATH, "r"

多线程并发编程

前言 多线程并发编程是Java编程中重要的一块内容,也是面试重点覆盖区域,所以学好多线程并发编程对我们来说极其重要,下面跟我一起开启本次的学习之旅吧. 正文 线程与进程 1 线程:进程中负责程序执行的执行单元线程本身依靠程序进行运行线程是程序中的顺序控制流,只能使用分配给程序的资源和环境 2 进程:执行中的程序一个进程至少包含一个线程 3 单线程:程序中只存在一个线程,实际上主方法就是一个主线程 4 多线程:在一个程序中运行多个任务目的是更好地使用CPU资源 线程的实现 继承Thread类 在j

多线程并发

转于http://m.blog.csdn.net/blog/haolongabc/7249098 浅谈java内存模型        不同的平台,内存模型是不一样的,但是jvm的内存模型规范是统一的.其实java的多线程并发问题最终都会反映在java的内存模型上,所谓线程安全无非是要控制多个线程对某个资源的有序访问或修改.总结java的内存模型,要解决两个主要的问题:可见性和有序性.我们都知道计算机有高速缓存的存在,处理器并不是每次处理数据都是取内存的.JVM定义了自己的内存模型,屏蔽了底层平台

对JAVA多线程 并发编程的理解

对JAVA多线程并发编程的理解 Java多线程编程关注的焦点主要是对单一资源的并发访问,本文从Java如何实现支持并发访问的角度,浅析对并发编程的理解,也算是对前段时间所学的一个总结. 线程状态转换 Java语言定义了5中线程状态,在任何一个时间点,一个线程只能有且只有其中一种状态,这5中状态分别是: ?  新建(New):创建后尚未启动的线程处于这种状态 ?  运行(Runable):Runable包括了操作系统线程状态中的Running和Ready,也就是处于此状态的线程可能正在执行,也有可

Java多线程并发技术

Java多线程并发技术 参考文献: http://blog.csdn.net/aboy123/article/details/38307539 http://blog.csdn.net/ghsau/article/category/1707779 http://www.iteye.com/topic/366591 JAVA多线程实现方式主要有三种:继承Thread类.实现Runnable接口.使用ExecutorService.Callable.Future实现有返回结果的多线程.其中前两种方式

java多线程并发编程与CPU时钟分配小议

我们先来研究下JAVA的多线程的并发编程和CPU时钟振荡的关系吧 老规矩,先科普 我们的操作系统在DOS以前都是单任务的 什么是单任务呢?就是一次只能做一件事 你复制文件的时候,就不能重命名了 那么现在的操作系统,我一边在这边写BLOG,一边听歌,一边开着QQ,一边…………………… 显然,现在的操作系统都是多任务的操作系统 操作系统对多任务的支持是怎么样的呢? 每打开一个程序,就启动一个进程,为其分配相应空间(主要是运行程序的内存空间) 这其实就支持并发运行了 CPU有个时钟频率,表示每秒能执行