zoukankan      html  css  js  c++  java
  • 线程

    线程

    线程应用场景:

    (1):希望获得更多操作系统资源尽快处理我们的业务,缩短处理的时间

    (2) 如果一个非常复杂的操作.需要占用非常长的时间,而WinFrom又不允许阻塞UI线程

    后台线程

    创建线程

     1   private void button2_Click(object sender, EventArgs e)
     2         {
     3             //创建一个委托指向其中一个方法
     4             ThreadStart threadStart = new ThreadStart(StartCaul);
     5             //创建线程
     6             Thread myThread = new Thread(threadStart);//可以直接放方法名进去 StartCaul
     7             //开启线程
     8             myThread.Start();
     9             //设置线程的优先级
    10             myThread.Priority = ThreadPriority.Normal;//建议操作系统将创建的线程优先级设置为最高。
    11             //可以给线程起个名字
    12             myThread.Name = "myThreadBB";
    13             //终止线程
    14             myThread.Abort();
    15             //阻塞主线程执行
    16             myThread.Join(1000);
    17             //设置后台线程
    18             myThread.IsBackground = true;
    19 
    20         }
    创建线程

    控制线程结束

     1    bool isStop = false;
     2         private void StartCaul()
     3         {
     4             int a = 0;
     5             for (int i = 0; i < 600000000; i++)
     6             {
     7                 if (!isStop)
     8                 {
     9                     a = i;
    10                 }
    11                 else
    12                 {
    13                   
    14                 }
    15             }
    16             //MessageBox.Show(a.ToString());
    17             this.textBox1.Text = a.ToString();
    18         }
    控制线程结束

    微软提供跨线程检测 不建议把他用一下方法取消

    TextBox.CheckForIllegalCrossThreadCalls = false;

    跨线程访问

     1  /// <summary>
     2         /// 完美的跨线程访问   要访问主线程创建的TextBox 需设置跨线程访问
     3         /// </summary>
     4         /// <param name="sender"></param>
     5         /// <param name="e"></param>
     6         private void button4_Click(object sender, EventArgs e)
     7         {
     8             //创建一个线程
     9             Thread thread1 = new Thread(ShowResult);
    10             //设置为后台线程
    11             thread1.IsBackground = true;
    12             thread1.Start();
    13         }
    14         private void ShowResult()
    15         {
    16             int a = 0;
    17             for (int i = 0; i < 600000000; i++)
    18             {
    19                
    20                 a = i;
    21               
    22             }
    23                  //现在就是对文本框进行跨线程访问 返回是true
    24             if (this.textBox1.InvokeRequired)//是否要对文本框进行跨线程访问。
    25             {
    26                 //Invoke:去找创建TextBox的线程(主线程(UI线程)),由主线程完成委托方法的调用。
    27                 //后面2个参数给方法传值
    28                 //泛型约束<TextBox, string>
    29                 this.textBox1.Invoke(new Action<TextBox, string>(ShowTextBoxValue), this.textBox1, a.ToString());//
    30             }
    31             else
    32             {
    33                 this.textBox1.Text = a.ToString();
    34             }
    35         }
    36         //给文本框赋值函数 不需要返回值
    37         private void ShowTextBoxValue(TextBox txt,string value)
    38         {
    39             txt.Text = value;
    40 
    41         }
    完美的跨线程访问

    线程执行带参数的方法

     1  private void button3_Click(object sender, EventArgs e)
     2         {
     3             //创建一个List集合
     4             List<int> list = new List<int>() {1,2,3,4,5 };
     5             //传一个方法
     6             ParameterizedThreadStart parThreadStart = new ParameterizedThreadStart(Show);
     7             Thread thread1 = new Thread(parThreadStart);
     8             //标记为后台线程
     9             thread1.IsBackground = true;
    10             //Start方法有2个参数 向方法传递参数
    11             thread1.Start(list);
    12         }
    13         private void Show(object obj)
    14         {
    15             //遍历list集合输出
    16             List<int> list = obj as List<int>;
    17             foreach (int i in list)
    18             {
    19                 MessageBox.Show(i.ToString());
    20             }
    21         }
    线程执行带参数的方法

    多线程同步

    当多个线程访问同一资源时要加锁,多用户并发问题.加锁可以解决多线程访问同一资源问题,但是它带来的问题比较慢

     1      //开启2个线程调同一个方法 当多个线程访问同一资源时要加锁
     2 
     3         private void button5_Click(object sender, EventArgs e)
     4         {
     5           //  this.textBox1.Text = "safasdfd";
     6             Thread thread1 = new Thread(AddSum);
     7             thread1.IsBackground = true;
     8             thread1.Start();
     9 
    10             Thread thread2 = new Thread(AddSum);
    11             thread2.IsBackground = true;
    12             thread2.Start();
    13         }
    14         //
    15         private static readonly object obj = new object();
    16 
    17         private void AddSum()
    18         {
    19             lock (obj)  
    20             {
    21 
    22                 for (int i = 0; i < 2000; i++)
    23                 {
    24                     int a = Convert.ToInt32(this.textBox1.Text);
    25                     a++;
    26                     this.textBox1.Text = a.ToString();
    27                 }
    28             }
    29            
    30         }
    View Code

    浏览器对服务器发送请求,等于开启了一个线程,线程本身是消耗资源的,一台web服务器挺不住太多线程,CPU来回切换消耗资源

    lock 是一个语法糖  实际写法Monitor.Enter(obj)

    线程池

     1 什么时候用线程池? 什么时候手动创建线程?
     2 1,能用线程池的就用线程池
     3 
     4 2.我们想手动关闭线程的话那么必须手动创建  Abort() Join()
     5 
     6 3.我们需要对线程池的线程的优先级做设置的情景下,只能使用手动创建线程
     7 
     8 4.如果执行的线程执行时间特别长,建议手动创建线程.
     9 
    10 线程池:提高了线程的利用率,非常适合工作任务比较小,而且又需要使用单独的线程来解决的问题.
    11 
    12 线程切换消耗资源,cpu在切换线程的时候,需要把当前线程执行的状态保持到寄存器里面去.
    13 
    14 线程创建非常消耗资源.线程创建非常慢,占用大量的内存空间,每个线程最少1M内存开销.
    线程池介绍
     1   Stopwatch  sw =new Stopwatch();
     2             sw.Start();
     3             for (int i = 0; i < 1000; i++)
     4             {
     5                new Thread(() =>
     6                  {
     7                       int i2 = 1 + 1;
     8                      
     9                     }).Start();
    10            }
    11            sw.Stop();
    12            Console.WriteLine(sw.Elapsed.TotalMilliseconds);
    13 
    14             //重新开始计时
    15           sw.Reset();
    16            sw.Restart();
    17            for (int i = 0; i < 1000; i++)
    18           {
    19                //从线程池取出一个线程
    20               ThreadPool.QueueUserWorkItem(new WaitCallback(PoolCallBack), "sssss"+i);
    21                //ThreadPool.GetMaxThreads
    22            }
    23            sw.Stop();
    24            Console.WriteLine(sw.Elapsed.TotalMilliseconds);
    25 
    26            Console.ReadKey();
    27           
    28         }
    29         private static void PoolCallBack(object state)
    30         {
    31             int i = 1 + 1;
    32 
    33         }
    手动开启线程与使用线程池时间比较
  • 相关阅读:
    ASP.NET MVC5+EF6+EasyUI 后台管理系统(28)-系统小结
    用谷歌浏览器来当手机模拟器
    解决PHP使用CVS导出Excel乱码问题
    Linux系统中关于Sqlite3中文乱码问题及解决办法
    解决excel日期变成数字的问题
    基于IE的多标签的浏览器-世界之窗2.4
    Thinkphp 获取所有子分类或父分类ID
    PhpExcel 删除默认的Sheet
    Mysql 创建表时错误:Tablespace for table `tablexx` exists. Please DISCARD the tablespace before IMPORT.
    关于ThinkPhp中getField方法存在的问题
  • 原文地址:https://www.cnblogs.com/ligtcho/p/6653813.html
Copyright © 2011-2022 走看看