这个示例主要演示的是在多进程操作数据库时,如何避免并发重复数据入库的例子。

过多的线程理论不再阐述,网上、书上皆有。

项目采用 Asp.Net Framework 4.5 / Mysql 5.4 数据库。

首先创建一个 LockInsertDB.cs 文件,这个文件用来实现数据库添加;

 1 using System;
 2 using MySql;
 3 using MySql.Data.MySqlClient;
 4 using System.Collections.Generic;
 5 using System.Linq;
 6 using System.Text;
 7 using System.Threading.Tasks;
 8 
 9 namespace DBImportTool
 {
     public class LockInsertDB : Common
     {
         private object obj = new object();
         /// <summary>
         /// 添加测试数据
         /// </summary>
         /// <param name="path">字段内容</param>
         /// <param name="tname">线程名称</param>
         public void InsertTestDB(string path, object tname)
         {
             MySql.Data.MySqlClient.MySqlConnection conn = new MySql.Data.MySqlClient.MySqlConnection("Server=10.17.1.57; Database=videodb; Uid=root; Pwd=xingzhi");
             try
             {
                 conn.Open();//打开连接
                 MySql.Data.MySqlClient.MySqlCommand cmd = new MySql.Data.MySqlClient.MySqlCommand();
                 cmd.Connection = conn;
                 //加入多线程,排它锁机制.
                 lock (obj)
                 {
                     string select = "SELECT * FROM `tbl_test` WHERE `filepath` = '" + path + "'";
                     cmd.CommandText = select;
                     object val = cmd.ExecuteScalar();
                     if (val == null)
                     {
                         string sql = "INSERT INTO `tbl_test` (`filepath`, `addtime`) VALUES ('" + path + "', NOW());";
                         cmd.CommandText = sql;
                         cmd.ExecuteNonQuery();
                         P(DateTime.Now.ToString() + "\t" + tname + "\tOK\t" + path + "\n");
                     }
                     else
                     {
                         P(DateTime.Now.ToString() + "\t" + tname + "\t已存在\t" + path + "\n");
                     }
                 }
             }
             catch
             {
 
             }
             finally
             {
                 //关闭连接
                 conn.Close();
             }
         }
         /// <summary>
         /// 测试输出
         /// </summary>
         /// <param name="str">输出内容字符串</param>
         public void P(string str)
         {
             Console.Write(str);
         }
     }

65 }

再创建一个控制台工程,Main方法代码如下:

 1 using System;
 2 using System.Threading;
 3 using System.IO;
 4 using System.Collections.Generic;
 5 using System.Linq;
 6 using System.Text;
 7 using System.Threading.Tasks;
 8 namespace DBImportTool
 9 {
     public class Mcqueen
     {
         static void Main(string[] args)
         {
             Run();
             Console.ReadLine();
         }
         /// <summary>
         /// 进程数量.
         /// </summary>
         static int tnum = ;
         /// <summary>
         /// 所对象
         /// </summary>
         static object obj = new object();
         /// <summary>
         /// 线程数组.
         /// </summary>
         static Thread[] threadarr = new Thread[tnum];
         /// <summary>
         /// 数据库插入对象.
         /// </summary>
         static LockInsertDB mdb = new LockInsertDB();
         /// <summary>
         /// 运行函数
         /// </summary>
         public static void Run()
         {
             for (int i = ; i < tnum; i++)
             {
                 Thread t = new Thread(T1);
                 threadarr[i] = t;
                 threadarr[i].Name = "Thread " + i.ToString() + " :";
             }
             int y = ;
             while (y < tnum)
             {
                 threadarr[y].Start(threadarr[y].Name);
                 y++;
             }
         }
         /// <summary>
         /// 读取磁盘文件路径.
         /// </summary>
         /// <param name="tname">线程名称</param>
         public static void T1(object tname)
         {
             DirectoryInfo di = Directory.CreateDirectory(@"F:\邢智的文件\");
             GetFiles(di, tname);
         }
         /// <summary>
         /// 采用对列入栈模式对列遍历文件夹结构.
         /// </summary>
         /// <param name="di">目录对象</param>
         /// <param name="tobj">线程名称</param>
         private static void GetFiles(DirectoryInfo di,object tobj)
         {
             int sgin = ;
             Stack<DirectoryInfo> stack_dir = new Stack<DirectoryInfo>();
             DirectoryInfo dir = di;
             stack_dir.Push(di);
             while (stack_dir.Count != )
             {
                 dir = stack_dir.Pop();
                 DirectoryInfo[] diarr = dir.GetDirectories();
                 foreach (DirectoryInfo d in diarr)
                     stack_dir.Push(d);
                 FileInfo[] files = dir.GetFiles();
                 foreach (FileInfo f in files)
                 {
                     mdb.InsertTestDB(f.FullName.Replace("\\", "\\\\"), tobj);
                     Thread.Sleep();
                     sgin++;
                 }
             }
         }
         public static void P(string str)
         {
             Console.Write(str);
         }
     }

91 }

static LockInsertDB mdb = new LockInsertDB();

一开始把这句初始化对象放到了private static void GetFiles(DirectoryInfo di,object tobj) 函数里面,虽然在后续的执行过程中没有任何问题,

但是初始化运行线程时导致了进程并发进入lock锁中,后来研究一下原因,是因为每个进程都在实例化化它的时候都会在lock中分配一个标识符,

这样一来,假如A进程内实例化了A1,那么当B进程进来之后,B却不认识A线程内的A1,因此lock也就对A1不起作用了。

因此把这个类跳出线程而放到一个全局中去实例化,也就不存在这个lock失效的问题了。

运行结果如下:

如果需要模拟更多的进程用户,只需要把 tnum = 2 的数值改一下即可。

多进程用户并发处理Demo(C#版)的更多相关文章

  1. EasyUI+MVC+EF简单用户管理Demo(问题及解决)

    写在前面 iframe-src EntityFramework版本 connectionStrings View.Action.页面跳转 EasyUI中DataGrid绑定 新增.修改和删除数据 效果 ...

  2. vue入门:用户管理demo

    该demo纯前端实现 使用到vue技术点: 1.在该demo中使用到的vue指令:{{}}. v-if. v-model. @click v-for 2.在该demo中使用到的事件修饰符: .prev ...

  3. Win7隐藏登录界面中的用户(不建议HOME版使用)

    一天一點 能登多高,靠的不是双脚!能看多远,靠的不是双眼!人生路,贵在坚持! Win7隐藏登录界面中的用户(不建议HOME版使用) Win7中如何隐藏不想出现在登录界面中的用户 在Windows系统管 ...

  4. PHP多进程学习(一)__来初步了解一下PHP多进程及简单demo

    php是一门单进程弱类型的语言,PHP处理多并发主要是依赖服务器或PHP-FPM的多进程及它们进程的复用,多进程的作用优点大家可以去网上了解,PHP实现多进程在实际项目中意义也是不容小觑的.比如:日常 ...

  5. WordPress 前端投稿/编辑发表文章插件 DJD Site Post(支持游客和已注册用户)汉化版 免费下载

    插件简介 前面逍遥乐给大家推荐了 WordPress用户前端化专业版WP User Frontend Pro WordPress中文汉化插件v2.1.9 今天逍遥乐给大家带来的wordpress插件是 ...

  6. apache通过.htaccess(rewrite)判断手机电脑跳转-手机用户重定向到手机版

    自动判断.重定向的办法也有几种: 使用网站构建的程序(例如PHP)来判断.重定向:使用服务器上的Web服务(例如Apache)来判断.重定向. 在Apache中设置重定向有两个办法: 在网站的http ...

  7. JavaCPP快速入门(官方demo增强版)

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  8. hadoop streaming编程小demo(python版)

    大数据团队搞数据质量评测.自动化质检和监控平台是用django,MR也是通过python实现的.(后来发现有orc压缩问题,python不知道怎么解决,正在改成java版本) 这里展示一个python ...

  9. spring boot一个简单用户管理DEMO

    概述 该Demo旨在部署一个简单spring boot工程,包含数据编辑和查看功能 POM配置 <?xml version="1.0" encoding="UTF- ...

随机推荐

  1. cloudstack4.4新增功能前瞻

    cloudstack4.4.0新功能前瞻 转载请注明地址:http://blog.csdn.net/zt689/article/details/37698989 1.   cloudstack4.4. ...

  2. 虚拟机下opensips 启动

    先启动MYSQL mysql:service mysqld start 然后启动RTP代理 rtpproxy -l 192.168.6.199 -s udp:192.168.6.199:7890 -F ...

  3. nand烧写分析/内核在启动过程中式如何将这个文件映射成/目录及各子目录的?

    我用的是ramdisk.image.gz,烧写在flash的0x10140000处 我不太明白内核在启动过程中式如何将这个文件映射成/目录及各子目录的? 如果ramdisk.image.gz在flas ...

  4. ORACLE数据库不同故障下的恢复总结

    ORACLE数据库不同故障下的恢复总结1. 非归档模式下丢失或损坏的文件--1.1 数据文件--启动数据库的状态到MOUNT--恢复方法:通过之前创建的数据库完整备份,修复整个数据库,不过备份之后发生 ...

  5. Linux常见目录作用

    Linux中一切皆文件 文件类型: 一般文件 - 目录文件 d 链接文件 l 块设备   b    (以块为单位进行操作,比如硬盘) 字符设备 c  (以字符为单位进行操作,比如主存) socket  ...

  6. apache安装扩展模块

    apache 安装扩展模块 1,首先要确认你是否加载了mod_so模块,这个就是你在编译前参数配置的时候添加-enable-so(启用DSO).如果你没有这模块的话,是无法安装扩展模块的. /usr/ ...

  7. PHP中的的一个挺好用的函数 array_chunk

  8. 终极解法According to TLD or attribute directive in tag file, attribute select does not accept any expressions

    3天硬是是把这个问题解决了 有时候突然上个厕所灵感就来了 第一次向用JSTL解析xml 然后我想遍历整个xml文档打印出来 居然不让我输入变量 那让我怎么办啊 在网上各种找答案 说什么<%@ t ...

  9. Spring 入门 Ioc-Annotation

    通过对XML版本进行修改:http://www.cnblogs.com/likailan/p/3446821.html 一.导入 Spring 所需要的包 spring-framework-2.5.6 ...

  10. iOS学习笔记-死锁deadlock理解

    1.首先看一下官方文档的解释,这个block的队列是同步执行的,不像异步,这个方法直到block执行完毕才会返回 2.主线程一旦开启,就要先把自己的代码执行完成之后,才去执行加入到主队列中的任务 De ...