C#   发布时间:2022-04-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了C#多线程基础大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

线程基础

一个进程由若干个线程组成,线程是程序执行的基本原子单位。线程是"进程"中某个单一顺序的控制流,线程是进程中的一个基本执行流,每个线程都有自己专属的寄存器(程序计数器、栈指针等),代码共享区,不同的线程可以执行同样的方法

    多线程可以实现并行处理,可以避免某项任务长时间占用cpu时间,需要注意的是,多线程程序对于效率,应该根据任务不同的要求来选择。

线程的命名空间System.Threading

    Thread类是线程中最重要的一个,Thread类提供了创建并控制线程,设置其优先级并获取其状态的方法

    Thread类的声明:

class ThreadSimple

{

@H_801_40@//静态线程函数

public static void ThreadMethodExample()

{

}

}

//调用静态方法

Thread threadSimple = new Thread(ThreadSimple.ThreadMethodExamplE);

或:

void ThreadMethodExample()

{

}

//调用静态方法

//Thread threadSimple = new Thread(ThreadSimple.ThreadMethodExamplE);

Thread(ThreadStart(ThreadMethodExamplE));

}

  1. 线程启动、结束

    Thread类的常用方法

    1. IsAlive:判断线程是否处于活动状态
    2. Name:线程的名称
    3. Priority:ThreadPriority枚举类型,代表线程的优先级{Normal,AboveNormal,BelowNormal,Highest,LoWest}
    4. ThreadState:ThreadState枚举类型,代表线程的状态 { Running(线程已启动,正在执行),Stoprequested(正在请求停止此线程),Suspendrequested(正在请求挂起此线程),BACkground(线程正在被作为后台线程执行),Unstarted(尚未启动线程),Stopped(线程已经停止),WaitSleepJoin(线程已经被阻止),Suspended(线程已经挂起),Abortrequested(对线程调用了Thread.abort()方法但是线程尚未收到试图终止它的挂起的System.Threading.ThreadAbortException),Aborted(线程状态包括Abortrequested,并且该线程现在已死,但其状态尚未更改为Stopped) }
    5. Start:启动一个线程
    6. Suspend:挂起一个线程的运行(暂停、中断)
    7. Resume:继续被挂起的线程,恢复被Suspend()方法挂起的线程的执行
    8. Abort():结束一个线程的运行,终止线程
    9. Sleep():线程的休眠,使线程进入一定时间的休眠状态,时间一到,线程继续执行
  2. 线程间数据同步
    1. 线程间数据共享

      多线程编程中,如果线程间需要共享数据,需要把共享的数据设置为静态类型的,此时可以使用static关键字

    2. Lock语句同步数据访问

      线程之间的同步和通信处理,两个线程需要同时操作一个队列,一个线程进行添加操作,另一个线程进行取用元素操作。

      lock关键字将语句块标记为临界区,方法获取给定对象的互斥锁,执行语句,然后释放该锁。Lock的语法:lock(expression)statemenT_Block【其中expression是加锁对象,必须是引用类型,不能是数值类型,statemenT_Block代表正在访问的共享资源的程序段】,

      lock语句可以很好地实现互斥操作,从而保护数据在某个时刻内只有一个线程可以操作该数据,直至操作完成才允许其他线程进行操作,这样就实现了按顺序操作的设计,从而避免不可预料的情况发生。

public static void MethodSubB()

{

do

lock(lockExamplE)

i-=1;

Console.WriteLine("线程2开始,共享数据为:i={0}",i);

Thread.Sleep(2000); //线程A休眠2秒

Console.WriteLine("线程2结束,共享数据值i={0}",1)"> }

} while (true);

}

    3.Mutex类同步数据访问
    只向某个线程授予对共享资源的独占访问权,如果一个获取了互斥体,那么想要获取该互斥体的其他线程将被挂起,直到这个线程释放该互                 斥体。

    线程可以使用Mutex.WaitOne()方法释放这个对象,而在此期间,其他想要获取这个Mutex对象的线程都只能等待。

 

    4.Monitor类同步数据访问数

@H_130_7@monitor类用于锁定对象,一个线程只有得到这把锁才能对该对象进行操作,对象锁保证了在可能引起混乱的情况下,一个时刻只有一个线程可以访问这个对象

@H_130_7@monitor必须和一个具体的对象相关联,但由于它是一个静态类,所以不能使用它来定义对象,而且它的所有方法都是静态的,不能使用对象来引用。

一个线程@L_816_11@monitor.Enter()方法锁定对象时,这个对象就归它所有了,其他线程想要访问这个对象,只有等待它@L_816_11@monitor.Exit()方法释放锁。

            Monitor类主要成员

 

Enter

在指定对象上获取排他锁

Exit

释放指定对象上的排它锁

Pluse

通知等待队列中的线程锁定对象状态的更改

PluseAll

通知所有的等待线程对象状态的更改

TryEnter

试图获取指定对象上的排他锁

Wait

释放对象上的锁并阻止当前线程,直到它重新获取该锁

 

private static Object sObjectA = Object();

Object sObjectB = void DemoA()

{

if(@H_731_74@monitor.TryEnter(sObjectA,1000))

{

Thread.Sleep(1000);

if (@H_731_74@monitor.TryEnter(sObjectB,2000))

{

@H_731_74@monitor.Exit(sObjectB);

}

else

{

Console.WriteLine("TryEnter SObjectB超时...");

}

@H_731_74@monitor.Exit(sObjectA);

}

"执行DemoA");

}

void DemoB()

{

@H_127_46@monitor.Exit(sObjectA);

}

"TryEnter SObjectA超时...");

}

@H_731_74@monitor.Exit(sObjectB);

}

"执行DemoB");

}

void Main(String[] args)

{

Thread threadA = Thread(DemoA);

Thread threadB = Thread(DemoB);

threadA.Start();

threadB.Start();

Thread.Sleep(4000);

"线程结束");

}

 

    5.带参数线程

    在不传递参数的情况下,可以使用ThreadStart代理来执行函数,如果要传递参数给执行函数,则@R_675_9901@arameterizedThreadStart代理来链接函数

    Thread类的4个重载的构造函数

 

      1.Thread(ThreadStart)[初始化Thread类的新实例]

      2.Thread(ParameterizedThreadStart)

      [初始化Thread类的新实例,指定允许对象在线程启动时传递给线程的委托]

      3.Thread(ParameterizedThreadStart,Int32)

      4.Thread(ThreadStart,Int32)

      [初始化Thread类的新实例,并指定线程的最大堆栈]

例:

ThreadDemo

{

int paraA,paraB;

void MethodDemo()

{

"paraA={0},paraB={1}",paraA,paraB);

}

void Print(object obj)

{

"传入的参数是{0}",obj.ToString());

}

}

String[] args)

{

ThreadDemo A = ThreadDemo();

A.paraA = 2;

A.paraB = 3;

ThreadStart(A.MethodDemo));

threadA.Start();

ParameterizedThreadStart(ThreadDemo().Print));

threadB.Start(" 这是传入的参数");

 

 

Console.Write("Press any key to conTinue...");

Console.ReadKey();

}

 

  6.线程池ThreadPool

线程池是可以在后台执行多个任务的线程集合,这使得主线程可以自由地异步执行其他任务。一旦池中的某个线程任务完成,它将返回到等待线程队列中等待在此被使用。线程池线程都是后台线程。

以下情况应该使用单独的线程不宜使用线程池

1.线程需要指定优先级

2.线程执行的时间较长

3.线程在单独的线程apartment中

4.在线程执行的过程中对线程存在操作

static void MethodA(object num)

{

int QueueNum = (int)num;

Console.WriteLine("线程号:{0}",QueueNum);

//输出空行,为了美观

Console.WriteLine();

}

String[] args)

{

for (int i = 0; i < 5; i++)

{

//在线程池中创建线程池线程来执行指定的方法(用WaitCallBACk来表示),并将此线程排入线程池的队列等待执行

ThreadPool.QueueUserWorkItem(WaitCallBACk(MethodA),i);

}

}

大佬总结

以上是大佬教程为你收集整理的C#多线程基础全部内容,希望文章能够帮你解决C#多线程基础所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签: