博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Thread 初学(二)——线程同步
阅读量:6153 次
发布时间:2019-06-21

本文共 7533 字,大约阅读时间需要 25 分钟。

 

在讨论thread的常用方法之前,有必要先说一说IsBackground属性。废话少说上代码。

1   private void Form1_Load(object sender, EventArgs e) 2         { 3             Thread t = new Thread(run); 4             t.Start(); 5             t.IsBackground=true; // 设置是否为后台线程 6         } 7         public void run() 8         { 9             while (true)10             {11                 Thread.Sleep(1000);12             }13         }

加注释代码是设置IsBackground属性,如果设置为true,当主线程结束的时候,此线程必然结束。如果设置成false或者是不设置(就是注释掉第五行代码),就为前台线程,当主线程结束时,他也不结束。任然运行着。

下面记录线程同步学习笔记

 

线程同步可以使用以下三个类进行管理Interlocked(互锁类)Monitor(管理类)

Mutex(互斥体),还有一个简单的方法就是Lock();

Interlocked中常用的方法:

根据方法介绍,很明显如果我们的程序中需要做到线程同步,就需要一个自定义的“计数器”

以下是代码作为一个简单的线程同步例子:

界面效果图

代码:

private static long numberOfusedSpace = 0;//计数器也是个控制量用于互锁        int lenth = 0;        private void button1_Click(object sender, EventArgs e)        {            if (button1.Text.Contains("开始"))            {                richTextBox1.ReadOnly = true;                textBox1.ReadOnly = true;                 richTextBox2.ReadOnly = true;                lenth = richTextBox1.Text.Trim().Length;                Thread threadReadPoolA = new Thread(ReadPoolA);                Thread threadWritePoolB = new Thread(WritePoolB);                threadReadPoolA.IsBackground = true;                threadWritePoolB.IsBackground = true;                threadReadPoolA.Start();                threadWritePoolB.Start();                button1.Text = "清空 重来";            }            else            {                richTextBox1.ReadOnly = false;                textBox1.ReadOnly = true;                richTextBox2.ReadOnly = false;                foreach (Control temp in this.Controls)                {                    if (temp.GetType().ToString().Contains("TextBox"))                    {                        temp.Text = "";                    }                }                button1.Text = "开始流动;            }        }        ///         ///读取池子中的数据,并将它写入到管道(计数器)中        ///         private void ReadPoolA()        {            UserControl.CheckForIllegalCrossThreadCalls = false;            string s = richTextBox1.Text.Trim();                        while (richTextBox1.Text.Trim().Length > 0)            {                while (Interlocked.Read(ref numberOfusedSpace) == 1)                {                    Thread.Sleep(300);                }                textBox1.Text = s[0].ToString();                Interlocked.Increment(ref numberOfusedSpace);                s = s.Substring(1);                richTextBox1.Text = s;                //Thread.Sleep(1000);            }        }        ///         /// 读取管道(计数器)中的数据,并将它写入到池子中        ///         private void WritePoolB()        {            UserControl.CheckForIllegalCrossThreadCalls = false;            while (richTextBox2.Text.Trim().Length < lenth)            {                while (Interlocked.Read(ref numberOfusedSpace) == 0)                {                    Thread.Sleep(300);                }                richTextBox2.AppendText(textBox1.Text);                textBox1.Text = "";                Interlocked.Decrement(ref numberOfusedSpace);                //Thread.Sleep(1000);            }        }

 

Monitor中常用的方法

 

根据上面的方法可以判断我们需要一个锁信号,一半情况下都是一个空的object类型。是不是可以设置其他类型呢?我们可以再以后空闲的时候尝试一下。

界面样式:

代码:

1 private static object lockobj = new object();  //锁对象 2         int lenth = 0;                                // 长¡è度¨¨ 3         private void button1_Click(object sender, EventArgs e) 4         { 5             lenth = richTextBox1.Text.Trim().Length; 6             Thread threadReadPoolA = new Thread(ReadPoolA); 7             Thread threadWritePoolB = new Thread(WritePoolB); 8             threadReadPoolA.IsBackground = true; 9             threadWritePoolB.IsBackground = true;10             threadReadPoolA.Start();11             threadWritePoolB.Start();12         }13         private void ReadPoolA()14         {15             UserControl.CheckForIllegalCrossThreadCalls = false;16             string temp = richTextBox1.Text.Trim();17             while (richTextBox1.Text.Trim().Length > 0)18             {19                 try20                 {21                     Monitor.Enter(lockobj);    //进入所对象锁定对象22                     textBox1.Text = temp[0].ToString();23                     temp = temp.Substring(1);24                     richTextBox1.Text = temp;25                     Monitor.Pulse(lockobj);   //唤醒在所对象上蹲着的线程告诉他你可以执行了,锁对象的状态已更改。26                     Monitor.Wait(lockobj);    //释放锁对象,并且不让自己立刻就获取该对象,但是要等着再次获得对象才能往下执行27 28                 }29                 catch (ThreadInterruptedException ex)30                 {31 32                     MessageBox.Show(ex.ToString());33                 }34                 finally35                 {36                     Monitor.Exit(lockobj);37                 }38             }39         }40         private void WritePoolB()41         {42             UserControl.CheckForIllegalCrossThreadCalls = false;43             while (richTextBox2.Text.Trim().Length < lenth)44             {45                 try46                 {47                     Monitor.Enter(lockobj);48                     richTextBox2.AppendText(textBox1.Text);49                     textBox1.Text = "";50                     Monitor.Pulse(lockobj);51                     Monitor.Wait(lockobj);52                 }53                 catch (ThreadInterruptedException ex)54                 {55                     MessageBox.Show(ex.ToString());56                 }57                 finally58                 {59                     Monitor.Exit(lockobj);60                 }61             }62         }63 64         private void button2_Click(object sender, EventArgs e)65         {66             foreach (Control c in this.Controls)67             {68                 if (c.GetType().ToString().Contains("TextBox"))69                 {70                     c.Text = "";71                 }72             }73         }

 

Mutex常用的方法:

界面:

做个功能简单的说明,这个功能是实现同时向1.txt文件写数据。

代码:

1 private void Form1_Load(object sender, EventArgs e) 2         { 3             System.Diagnostics.Process.Start("MetuxA.exe"); 4             Thread thread = new Thread(delegate() 5             { 6                 string filepat = @"e:\1.txt"; 7                 Mutex mt = new Mutex(false, "MutexRefObj"); 8                 while (true) 9                 {10                     try11                     {12                         mt.WaitOne();13                         if (!File.Exists(filepat))14                         {15                             File.Create(filepat);16                         }17                         string temp = "MetuxB: " + DateTime.Now.ToString() + "\r\n";18                         File.AppendAllText(filepat, temp);19                         Invoke(new EventHandler(delegate20                         {21                             richTextBox1.AppendText(temp);22                         }));23                     }24                     catch (ThreadInterruptedException ex)25                     {26                         MessageBox.Show(ex.ToString());27                     }28                     finally29                     {30                         mt.ReleaseMutex();31                     }32                     Thread.Sleep(500);33                 }34             });35             thread.IsBackground = true;36             thread.Start();37         }38     }39 40 41 A B两个类的代码几乎相同。

ps:在这里没有说明lock的使用方法,可能在明天或者是今天晚上我将温习一下lock和跨线程控件访问的控制。

 

转载于:https://www.cnblogs.com/xiaoch/archive/2012/07/04/2574163.html

你可能感兴趣的文章
关于JavaScript词法
查看>>
FreeSwitch中的会议功能(4)
查看>>
MySQL中创建用户分配权限(到指定数据库或者指定数据库表中)
查看>>
AutoReleasePool 和 ARC 以及Garbage Collection
查看>>
重新想象 Windows 8 Store Apps (9) - 控件之 ScrollViewer 基础
查看>>
乐在其中设计模式(C#) - 提供者模式(Provider Pattern)
查看>>
MVP Community Camp 社区大课堂
查看>>
GWT用frame调用JSP
查看>>
大型高性能ASP.NET系统架构设计
查看>>
insert select带来的问题
查看>>
EasyUI 添加tab页(iframe方式)
查看>>
mysqldump主要参数探究
查看>>
好记心不如烂笔头,ssh登录 The authenticity of host 192.168.0.xxx can't be established. 的问题...
查看>>
使用addChildViewController手动控制UIViewController的切换
查看>>
Android Fragment应用实战
查看>>
SQL Server查询死锁并KILL
查看>>
内存或磁盘空间不足,Microsoft Office Excel 无法再次打开或保存任何文档。 [问题点数:20分,结帖人wenyang2004]...
查看>>
委托到Lambda的进化: ()=> {} 这个lambda表达式就是一个无参数的委托及具体方法的组合体。...
查看>>
apache 伪静态 .htaccess
查看>>
unity3d 截屏
查看>>