zoukankan      html  css  js  c++  java
  • 多线程学习之限制同时运行的线程数量

    多线程学习之限制同时运行的线程数量

    最近闲暇之余,来搞搞,多线程学习,只为下个项目做准备,随着项目优化,开发,性能的考虑,慢慢要用到些以前不用的东西,先开始熟悉熟悉

    先把东西放上来,欢迎大家赐教,比较好久木玩这东西了,肯定不完善,希望大家提出宝贵意见啊(嘿嘿~~)

    大概功能描述:为了提高数据处理速度,把任务队列分别交给不同子线程去完成,同时对启动的新线程数量限制,避免线程数量过多照成机器卡壳

    复制代码
     1 using System;
     2 using System.Threading;
     3 namespace ThreadTest
     4 {
     5   class ThreadMaxNum
     6     {
     7         static int NowThCount = 0;//当前已启动线程数量
     8         static int MaxThCount = 5;//允许最大启动线程数量
     9         static int RunNum = 15;//当前有多少个要处理的程序[任务队列]
    10         public static void Run()
    11         {
    12             Thread NewTh;
    13             while (true)
    14             {
    15                 //当前没有活动线程,且 任务队列 为空 说明任务完成了
    16                 if (NowThCount == 0 && RunNum == 0)
    17                     break;
    18                 
    19                 //任务队列为空 ,但是又线程运行中,就让主线程休息 下,在判断
    20                 if (RunNum == 0 && NowThCount != 0) 
    21                 {
    22                     Thread.Sleep(2000);//休息
    23                     continue;//再次判断
    24                 }
    25 
    26                 //如果 当前活动线程数量 达到最大线程 就不在 开始新的任务
    27                 if (NowThCount >= MaxThCount)
    28                 {
    29                     Thread.Sleep(2000);//休息
    30                     continue;//再次判断
    31                 }
    32 
    33                 //有 队列>0,且没有达到最大
    34                 if (RunNum > 0 && NowThCount < MaxThCount)
    35                 {
    36                     //一个任务已经去执行了,应该减掉个,执行结果如何,这里不判断
    37                     RunNum--;
    38 
    39                     NewTh = new Thread(new ThreadStart(RunNewFun));
    40                     NewTh.Start();
    41                 }
    42             }
    43             Console.WriteLine("任务队列,执行完成:"+RunNum);
    44         }
    45         static void RunNewFun()
    46         {
    47             NowThCount++;//加个
    48 
    49             Console.WriteLine("我是线程:" + Thread.CurrentThread.ManagedThreadId);
    50             Thread.Sleep(3000);
    51             Console.WriteLine("我是线程:" + Thread.CurrentThread.ManagedThreadId + ".....结束");
    52 
    53             NowThCount--;//减去
    54         }
    55     }
    56 }
    复制代码

    NPOI导出Excel和基于office导出Excel表比较

    首先介绍一下NPOI吧。

    NPOI 是 POI 项目的 .NET 版本。POI是一个开源的Java读写Excel、WORD等微软OLE2组件文档的项目。
    使用 NPOI 你就可以在没有安装 Office 或者相应环境的机器上对 WORD/EXCEL 文档进行读写。NPOI是构建在POI 3.x版本之上的,它可以在没有安装Office的情况下对Word/Excel文档进行读写操作。
     
    NPOI的优势:
    (一)传统操作Excel遇到的问题:
    1、如果是.NET,需要在服务器端装Office,且及时更新它,以防漏洞,还需要设定权限允许.NET访问COM+,如果在导出过程中出问题可能导致服务器宕机。
    2、Excel会把只包含数字的列进行类型转换,本来是文本型的,Excel会将其转成数值型的,比如编号000123会变成123。
    3、导出时,如果字段内容以“-”或“=”开头,Excel会把它当成公式进行,会报错。
    4、Excel会根据Excel文件前8行分析数据类型,如果正好你前8行某一列只是数字,那它会认为该列为数值型,自动将该列转变成类似1.42702E+17格式,日期列变成包含日期和数字的。
    (二)使用NPOI的优势
    1、你不需要在服务器上安装微软的Office,可以避免版权问题。
    2、使用起来比Office PIAAPI更加方便,更人性化。
    3、你不用去花大力气维护NPOINPOI Team会不断更新、改善NPOI,绝对省成本。
     
    基于office导出到Excel实现:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    public static void ExportExcel(string fileName, DataGridView myDGV,bool isShowDialog)
          {
              string saveFileName = "";
              if (isShowDialog)
              {
                  //bool fileSaved = false;
                  SaveFileDialog saveDialog = new SaveFileDialog();
                  saveDialog.DefaultExt = "xls";
                  saveDialog.Filter = "Excel文件|*.xls";
                  saveDialog.FileName = fileName;
                  saveDialog.ShowDialog();
                  saveFileName = saveDialog.FileName;
                  if (saveFileName.IndexOf(":") < 0) return; //被点了取消
              }
              else
              {
                 // saveFileName = Application.StartupPath + @"\导出记录\" + fileName + ".xls";
                  saveFileName = fileName;
              }
              Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
              if (xlApp == null)
              {
                  MessageBox.Show("无法创建Excel对象,可能您的机子未安装Excel");
                  return;
              }
     
              Microsoft.Office.Interop.Excel.Workbooks workbooks = xlApp.Workbooks;
              Microsoft.Office.Interop.Excel.Workbook workbook = workbooks.Add(Microsoft.Office.Interop.Excel.XlWBATemplate.xlWBATWorksheet);
              Microsoft.Office.Interop.Excel.Worksheet worksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Worksheets[1];//取得sheet1
     
              //写入标题
              for (int i = 0; i < myDGV.ColumnCount; i++)
              {
                  worksheet.Cells[1, i + 1] = myDGV.Columns[i].HeaderText;
              }
              //写入数值
              for (int r = 0; r < myDGV.Rows.Count; r++)
              {
                  for (int i = 0; i < myDGV.ColumnCount; i++)
                  {
                      if (myDGV[i, r].ValueType == typeof(string)
                         || myDGV[i, r].ValueType == typeof(DateTime))//这里就是验证DataGridView单元格中的类型,如果是string或是DataTime类型,则在放入缓 存时在该内容前加入" ";
                      {
                          worksheet.Cells[r + 2, i + 1] = "'" + myDGV.Rows[r].Cells[i].Value;
                      }
                      else
                      {
                          worksheet.Cells[r + 2, i + 1] = myDGV.Rows[r].Cells[i].Value;
                      }
                  }
                  System.Windows.Forms.Application.DoEvents();
              }
              worksheet.Columns.EntireColumn.AutoFit();//列宽自适应
              //if (Microsoft.Office.Interop.cmbxType.Text != "Notification")
              //{
              //    Excel.Range rg = worksheet.get_Range(worksheet.Cells[2, 2], worksheet.Cells[ds.Tables[0].Rows.Count + 1, 2]);
              //    rg.NumberFormat = "00000000";
              //}
     
              if (saveFileName != "")
              {
                  try
                  {
                      workbook.Saved = true;
                      workbook.SaveCopyAs(saveFileName);
                      //fileSaved = true;
                  }
                  catch (Exception ex)
                  {
                      //fileSaved = false;
                      MessageBox.Show("导出文件时出错,文件可能正被打开!\n" + ex.Message);
                  }
     
              }
              //else
              //{
              //    fileSaved = false;
              //}
              xlApp.Quit();
              GC.Collect();//强行销毁
              // if (fileSaved && System.IO.File.Exists(saveFileName)) System.Diagnostics.Process.Start(saveFileName); //打开EXCEL
              MessageBox.Show(fileName + "保存成功", "提示", MessageBoxButtons.OK);
          }

     NPOI导出到Excel表实现:

    /// <summary>
            /// NPOI导出Excel,不依赖本地是否装有Excel,导出速度快
            /// </summary>
            /// <param name="dataGridView1">要导出的dataGridView控件</param>
            /// <param name="sheetName">sheet表名</param>
            public static void ExportToExcel(DataGridView dataGridView1, string sheetName)
            {
                SaveFileDialog fileDialog = new SaveFileDialog();
                fileDialog.Filter = "Excel|*.xls";
                if (fileDialog.ShowDialog() == System.Windows.Forms.DialogResult.Cancel)
                {
                    return;
                }
                //不允许dataGridView显示添加行,负责导出时会报最后一行未实例化错误
                dataGridView1.AllowUserToAddRows = false;
                HSSFWorkbook workbook = new HSSFWorkbook();
                ISheet sheet = workbook.CreateSheet(sheetName);
                IRow rowHead = sheet.CreateRow(0);
     
                //填写表头
                for (int i = 0; i < dataGridView1.Columns.Count; i++)
                {
                    rowHead.CreateCell(i, CellType.STRING).SetCellValue(dataGridView1.Columns[i].HeaderText.ToString());
                }
                //填写内容
                for (int i = 0; i < dataGridView1.Rows.Count; i++)
                {
                    IRow row = sheet.CreateRow(i + 1);
                    for (int j = 0; j < dataGridView1.Columns.Count; j++)
                    {
                        row.CreateCell(j, CellType.STRING).SetCellValue(dataGridView1.Rows[i].Cells[j].Value.ToString());
                    }
                }         
     
                using (FileStream stream = File.OpenWrite(fileDialog.FileName))
                {
                    workbook.Write(stream);
                    stream.Close();
                }
                MessageBox.Show("导出数据成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                GC.Collect();
            }

      经过比较:如果导出50000条int类型的数据,基于office导出需要10分钟左右的时间,NPOI导出则需要3秒钟左右的时间。

      NPOI导出时间截图如下:

    基于office导出时间截图如下:

    呵呵,看出来两者的速度了吧,并且NPOI用起来相当的灵活,第一次写博客,希望和大家共同分享,共同学习,共同进步!

  • 相关阅读:
    mysql常用命令
    mysql设置外网访问权限
    免费云服务部署项目
    使用虚拟主机部署Php项目总结
    github基本使用命令笔记
    git push -u origin master报错,error: failed to push some refs to 'https://github.com/Youlandawq/Qt.git' hint: Updates were rejected because the tip of your current branch is behind hint: its remote c
    centos7安装docker
    java设计模式之单例模式
    java se高级之多线程(一)
    jdbc编程
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3078180.html
Copyright © 2011-2022 走看看