`
kofsky
  • 浏览: 201625 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

C#多线程例(转)

阅读更多

 
转载自:http://blog.csdn.net/ilovemsdn/archive/2007/08/10/1735495.aspx (部分)

      多线程公用一个对象时,也会出现和公用代码类似的问题,这种问题就不应该使用lock关键字了,这里需要用到System.Threading中的一个类Monitor,我们可以称之为监视器,Monitor提供了使线程共享资源的方案。

  Monitor类可以锁定一个对象,一个线程只有得到这把锁才可以对该对象进行操作。对象锁机制保证了在可能引起混乱的情况下一个时刻只有一个线程可以访问这个对象。Monitor必须和一个具体的对象相关联,但是由于它是一个静态的类,所以不能使用它来定义对象,而且它的所有方法都是静态的,不能使用对象来引用。下面代码说明了使用Monitor锁定一个对象的情形:

        ......
  Queue oQueue
=new Queue();
   ...... 
  Monitor.Enter(oQueue);
  ......
//现在oQueue对象只能被当前线程操纵了
   Monitor.Exit(oQueue);// 释放锁 


  如上所示,当一个线程调用Monitor.Enter()方法锁定一个对象时,这个对象就归它所有了,其它线程想要访问这个对象,只有等待它使用Monitor.Exit()方法释放锁。为了保证线程最终都能释放锁,你可以把Monitor.Exit()方法写在try-catch-finally结构中的finally代码块里。对于任何一个被Monitor锁定的对象,内存中都保存着与它相关的一些信息,其一是现在持有锁的线程的引用,其二是一个预备队列,队列中保存了已经准备好获取锁的线程,其三是一个等待队列,队列中保存着当前正在等待这个对象状态改变的队列的引用。当拥有对象锁的线程准备释放锁时,它使用Monitor.Pulse()方法通知等待队列中的第一个线程,于是该线程被转移到预备队列中,当对象锁被释放时,在预备队列中的线程可以立即获得对象锁
 

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

/**//*** 例子来源:http://blog.csdn.net/ilovemsdn/archive/2007/08/10/1735495.aspx **/
namespace ConsoleApplication1
...{
    
public class Cell            //Cell为个被操作的对象的类
    ...//消费者线程将调用ReadFromCell()读取cellContents的内容并且显示出来
      
//生产者进程将调用WriteToCell()方法向cellContents写入数据

        
int cellContents;        // Cell对象里边的内容
        bool readerFlag = false// 状态标志,为true时可以读取,为false则正在写入
        public int ReadFromCell()
      
...{
          
lock (this// 关键字lock把一段代码定义为互斥段(critical section),
                      
//互斥段在一个时刻内只允许一个线程进入执行,而其他线程必须等待
        ...{
           
if (!readerFlag)//如果现在不可读取
           ...
               
try
                     
...{  //等待WriteToCell方法中调用Monitor.Pulse()方法
                Monitor.Wait(this);
                }

                
catch (SynchronizationLockException e)
                
...{
                    Console.WriteLine(e);
                }

                
catch (ThreadInterruptedException e)
                
...{
                Console.WriteLine(e);
             }

        }

        Console.WriteLine(
"Consume: {0}",cellContents);
        readerFlag 
= false//重置readerFlag标志,表示消费行为已经完成
        Monitor.Pulse(this);//通知WriteToCell()方法(该方法在另外一个线程中执行,等待中)
    }

    
return cellContents;
  }


    
public void WriteToCell(int n)
  
...{
    
lock(this)
    
...{
    
if (readerFlag)
    
...{
      
try
      
...{
        Monitor.Wait(
this);
      }

      
catch (SynchronizationLockException e)
      
...{//当同步方法(指Monitor类除Enter之外的方法)在非同步的代码区被调用
        Console.WriteLine(e);
      }

      
catch (ThreadInterruptedException e)
      
...{//当线程在等待状态的时候中止 
        Console.WriteLine(e);
      }

    }

    cellContents 
= n;
    Console.WriteLine(
"Produce: {0}",cellContents);
    readerFlag 
= true
    Monitor.Pulse(
this); //通知另外一个线程中正在等待的ReadFromCell()方法
    }

      }

    }




    
public class CellProducer// 生产者线程
    ...{
        Cell cell; 
// 被操作的Cell对象
        int quantity = 1// 生产者生产次数,初始化为1 

        
public CellProducer(Cell box, int request)
        
...{
            
//构造函数
            cell = box;
            quantity 
= request;
        }

        
public void ThreadRun()
      
...{
        
for(int looper=1; looper<=quantity; looper++)
            cell.WriteToCell(looper); 
//生产者向操作对象写入信息
      }

    }


    
public class CellConsumer //消费者线程
    ...{
        Cell cell;
        
int quantity = 1;

        
public CellConsumer(Cell box, int request)
        
...{
            cell 
= box;
            quantity 
= request;
        }

        
public void ThreadRun()
        
...{
            
int valReturned;
            
for (int looper = 1; looper <= quantity; looper++)
                valReturned 
= cell.ReadFromCell();//消费者从操作对象中读取信息
        }

    }




    
public class MonitorSample
    
...{
        
//创建两个线程分别作为生产者和消费者
        
//使用CellProducer.ThreadRun()方法和CellConsumer.ThreadRun()方法对同一个Cell对象进行操作
        public static void Main(String[] args)
        
...{
            
int result = 0;//一个标志位,如果是0表示程序没有出错,如果是1表明有错误发生  
            Cell cell = new Cell();

            
//下面使用cell初始化CellProducer和CellConsumer两个类,生产和消费次数均为20次
            CellProducer prod = new CellProducer(cell, 20);
            CellConsumer cons 
= new CellConsumer(cell, 20);

            Thread producer 
= new Thread(new ThreadStart(prod.ThreadRun));
            Thread consumer 
= new Thread(new ThreadStart(cons.ThreadRun));
            
//生产者线程和消费者线程都已经被创建,但是没有开始执行 

            
try
            
...{
                producer.Start();
                consumer.Start();
                
//谁调用Join谁被阻塞,等待被调用的线程执行完之后再执行本身.
                producer.Join();
                consumer.Join();
                Console.ReadLine();
            }

            
catch (ThreadStateException e)
分享到:
评论

相关推荐

    C#多线程 C#多线程

    在C#编程中,多线程是一种允许程序同时执行多个任务的技术,它极大地提高了应用程序的性能和响应速度。本文将深入探讨C#中的多线程概念、线程池的使用以及如何通过实例理解其工作原理。 首先,多线程在C#中是通过`...

    C#多线程全面编程4例

    在C#编程中,多线程技术是一种关键的并发处理方式,它允许程序同时执行多个独立的任务,从而提高系统的效率和响应性。本教程通过四个具体的实例深入探讨C#中的多线程编程,涵盖建立线程、同步机制、加锁以及线程间的...

    c# 多线程任务中结束全部线程

    在C#中,多线程是程序设计中的一个重要概念,它允许程序同时执行多个操作,从而提高程序的效率和响应性。然而,在某些情况下,我们可能需要终止正在运行的所有线程,这通常发生在应用程序需要关闭或者某个关键错误...

    C#队列Queue多线程用法实例

    本实例将详细讲解如何在多线程中使用C#的Queue类。 首先,我们创建一个队列实例,通过`new Queue()`来指定存储的数据类型。在本例中,队列存储的是字符串类型(string),所以是`Queue&lt;string&gt;`。接着,我们填充...

    C# 多线程技术,在C#中使用多线程

    ### C#多线程技术 #### 创建和启动线程 在C#中,创建一个线程最简单的方法是通过`Thread`类。首先,需要定义一个线程委托,这个委托将作为线程的入口点。例如: ```csharp Thread trd1 = new Thread(new Thread...

    c#多线程顺序打印1-100数字-源码.rar

    在C#编程中,多线程技术是一种提升程序性能...总之,这个"ConsoleApp1"项目提供了一个实用的多线程编程实践,它展示了如何使用C#和`AutoResetEvent`来控制线程执行的顺序,对于学习和理解C#多线程编程具有很高的价值。

    C#多线程实例,超级好懂,附带Word说明文档

    通过实践这些例子,并结合Word文档的解释,你应该能够深入理解C#多线程编程的各个方面。 总结来说,C#的多线程特性使得开发人员能够编写出高效且响应迅速的应用程序。理解并熟练掌握多线程的创建、同步、通信和管理...

    C# 多线程教程三

    在深入探讨C#多线程应用的进阶技巧时,我们发现了一个有趣且实用的案例——如何通过修改类属性和方法来实现线程间的任务分配。这个案例来源于一个项目需求,其中疯狂工作室需要同时处理多项任务,而有效的任务分配...

    C# 如何挂起线程、休眠线程和终止线程(源码例)

    本文将深入探讨如何挂起线程、休眠线程以及终止线程,这些都是多线程编程中的关键概念。 首先,让我们了解线程的基本概念。线程是程序执行的流程,每个进程至少有一个线程。在多线程环境中,多个线程可以共享同一...

    多线程 C#多线程 多线程机制

    多线程技术在C#编程中扮演着至关重要的角色,特别是在现代高性能应用中,它可以显著提升CPU的利用率,实现并发执行多个任务。本文将深入探讨C#中的多线程机制,包括线程的创建、管理和同步,以及如何利用线程池和...

    c#多线程进度条参考资料WEb

    在本篇内容中,我们将深入探讨如何在C#中实现多线程与进度条的结合,以便更好地理解和应用这一技术。我们将围绕一个示例代码展开讨论,该代码旨在展示如何在一个Windows Forms应用程序中通过多线程更新进度条,并且...

    C#.NET多线程实例6个(包括多线程基本使用,多线程互斥等全部多线程使用实例)

    本实例集包含了六个关于C#.NET多线程的实战案例,涵盖了多线程的基本使用以及多线程间的互斥控制,旨在帮助开发者深入理解和熟练运用多线程技术。 一、多线程基本使用 多线程的基本使用包括创建线程、启动线程、...

    C# Socket多线程编程实例-聊天程序

    本文将深入探讨C#下的Socket多线程编程,以一个聊天程序为例,帮助读者理解和实践相关知识。 ### 套接字基本概念 套接字(Socket)是网络通信的基础,它提供了进程间双向通信的接口。在TCP/IP协议族中,套接字是...

    C#多线程摇奖机源码

    在这个“C#多线程摇奖机源码”项目中,我们可以深入理解如何利用多线程来实现一个模拟摇奖过程的应用。 1. **C#中的线程** C#提供了System.Threading命名空间,其中Thread类是用于创建和管理线程的核心类。通过...

    摇奖机C#源码多线程的例

    在本文中,我们将深入探讨如何使用C#编程语言来实现一个多线程的摇奖机程序。C#是一种广泛用于开发Windows应用程序、Web服务以及游戏的强类型、面向对象的语言。多线程是C#中一个重要的特性,它允许程序同时执行多个...

    C#多线程编程实例实战

    C#多线程编程在软件开发中扮演着重要的角色,特别是在高性能、高并发的应用场景下。多线程允许程序同时执行多个任务,提高系统资源的利用率。本实例实战主要探讨了如何解决“单个写入程序/多个阅读程序”的线程同步...

    C#多线程处理多个队列数据的方法

    在C#编程中,多线程处理多个队列数据是一种常见的并发执行策略,它能够提高程序的执行效率,尤其在处理大量数据时。本示例介绍了一种利用ThreadPool类和委托来实现多线程处理多个队列数据的方法。以下是详细的知识点...

    C#多线程应用探讨.pdf

    ### C#多线程应用探讨 #### 概述 C#作为一种现代的、面向对象的编程语言,自2000年由微软推出以来,已成为.NET框架上构建各种应用程序的首选工具之一。C#支持自由线程(free-threaded)应用程序的开发,这意味着多...

    全盘遍历查找文件(多线程)

    本文将详细讲解如何利用C#编程语言,结合多线程技术实现全盘遍历查找文件,并使用递归算法提高查找效率。 首先,让我们了解“全盘遍历查找文件”的基本概念。这指的是遍历计算机硬盘上的所有目录和子目录,查找符合...

    C#多线程 摇奖机 小软件 新手 附源码和图片资源

    总的来说,"C#多线程摇奖机"项目为初学者提供了一个实践多线程编程的实例。通过这个小软件,开发者可以学习到如何在C#中实现多线程,理解线程同步的重要性,并掌握如何处理UI与后台任务之间的交互。同时,这也是一个...

Global site tag (gtag.js) - Google Analytics