大佬教程收集整理的这篇文章主要介绍了C#多线程基础,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
线程基础
一个进程由若干个线程组成,线程是程序执行的基本原子单位。线程是"进程"中某个单一顺序的控制流,线程是进程中的一个基本执行流,每个线程都有自己专属的寄存器(程序计数器、栈指针等),代码共享区,不同的线程可以执行同样的方法。
多线程可以实现并行处理,可以避免某项任务长时间占用cpu时间,需要注意的是,多线程程序对于效率,应该根据任务不同的要求来选择。
线程的命名空间System.Threading
Thread类是线程中最重要的一个,Thread类提供了创建并控制线程,设置其优先级并获取其状态的方法。
Thread类的声明:
class ThreadSimple
public static void ThreadMethodExample()
}
}
Thread threadSimple = new Thread(ThreadSimple.ThreadMethodExamplE);
或:
void ThreadMethodExample()
}
//Thread threadSimple = new Thread(ThreadSimple.ThreadMethodExamplE);
Thread(ThreadStart(ThreadMethodExamplE));
}
Thread类的常用方法:
多线程编程中,如果线程间需要共享数据,需要把共享的数据设置为静态类型的,此时可以使用static关键字
线程之间的同步和通信处理,两个线程需要同时操作一个队列,一个线程进行添加操作,另一个线程进行取用元素操作。
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);
}
线程可以使用Mutex.WaitOne()方法释放这个对象,而在此期间,其他想要获取这个Mutex对象的线程都只能等待。
@H_130_7@monitor类用于锁定对象,一个线程只有得到这把锁才能对该对象进行操作,对象锁保证了在可能引起混乱的情况下,一个时刻只有一个线程可以访问这个对象。
@H_130_7@monitor必须和一个具体的对象相关联,但由于它是一个静态类,所以不能使用它来定义对象,而且它的所有方法都是静态的,不能使用对象来引用。
当一个线程@L_816_11@monitor.Enter()方法锁定对象时,这个对象就归它所有了,其他线程想要访问这个对象,只有等待它@L_816_11@monitor.Exit()方法释放锁。
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);
}
}
@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)
}
}
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,请注明来意。