线程的好处,我想都不必多说,博客园太多了;但个人对线程了解还比较基础,决定把学习线程记录下来(有一些例子来之博客园):
创建线程
暂停线程
等待线程
线程传参数
lock
Monitor
创建线程
Thread t = new Thread(PrintNumbers);//线程创建 t.Start();//开始线程PrintNumbers(); static void PrintNumbers() { Console.WriteLine("Starting..."); for (int i = 1; i < 10; i++) { Console.WriteLine(i); } }
暂停线程
sleep暂停线程;
Thread t = new Thread(PrintNumbersWithDelay); t.Start(); static void PrintNumbersWithDelay() { Console.WriteLine("Starting..."); for (int i = 1; i < 10; i++) { Thread.Sleep(2000); Console.WriteLine(string.Format("顺序{0},时间:{1}", i, DateTime.Now)); } }
sleep(2000);每隔2秒输出一次;
等待线程
Thread t = new Thread(Run); t.Start(); //Join相当于把Run方法内嵌如此 t.Join(); //该死的t.Join(),害的我主线程必须在你执行完后才能执行。 Console.WriteLine("我是主线程:" + Thread.CurrentThread.GetHashCode()); } static void Run() { //等待5s Thread.Sleep(5000); Console.WriteLine("我是线程:" + Thread.CurrentThread.GetHashCode()); }
线程传参数
var threadOne = new Thread(One); threadOne.Start("one"); threadOne.Join(); var threadTwo = new Thread(() => One("two")); threadTwo.Start(); threadTwo.Join(); var value = "three"; var threadThree = new Thread(() => One(value)); value = "four"; var threadFour = new Thread(() => One(value)); threadThree.Start(); threadFour.Start(); static void One(object obj) { Console.WriteLine(obj); }
在启动线程3,4时,变量value的值变成four,最后打印出four
lock
Console.WriteLine("不规则统计"); var c = new Counter(); var t1 = new Thread(() => TestCounter(c)); var t2 = new Thread(() => TestCounter(c)); var t3 = new Thread(() => TestCounter(c)); t1.Start(); t2.Start(); t3.Start(); t1.Join(); t2.Join(); t3.Join(); Console.WriteLine("总计: {0}",c.Count); Console.WriteLine("--------------------------"); Console.WriteLine("正确统计"); var c1 = new CounterWithLock(); t1 = new Thread(() => TestCounter(c1)); t2 = new Thread(() => TestCounter(c1)); t3 = new Thread(() => TestCounter(c1)); t1.Start(); t2.Start(); t3.Start(); t1.Join(); t2.Join(); t3.Join(); Console.WriteLine("总计: {0}", c1.Count); static void TestCounter(CounterBase c) { for (int i = 0; i < 100000; i++) { c.Increment(); c.Decrement(); } } class Counter : CounterBase { public int Count { get; private set; } public override void Increment() { Count++; } public override void Decrement() { Count--; } } class CounterWithLock : CounterBase { private readonly object _syncRoot = new Object(); public int Count { get; private set; } public override void Increment() { lock (_syncRoot) { Count++; } } public override void Decrement() { lock (_syncRoot) { Count--; } } } abstract class CounterBase { public abstract void Increment(); public abstract void Decrement(); }
加了锁和不加锁统计的结果完全不一样
Monitor
同步访问对象机制;在锁定的临界区中只允许让一个线程访问,其他线程排队等待。
1:Monitor.Enter和Monitor.Exit
for (int i = 0; i < 10; i++) { Thread t = new Thread(Run); t.Start(); } //资源 static object obj = new object(); static int count = 0; static void Run() { Thread.Sleep(10); //进入临界区 Monitor.Enter(obj); Console.WriteLine("当前数字:{0}", ++count); //退出临界区 Monitor.Exit(obj); }
2:Monitor.Wait和Monitor.Pulse
Wait: 暂时的释放资源锁,然后该线程进入”等待队列“中,那么自然别的线程就能获取到资源锁。
Pulse: 唤醒“等待队列”中的线程,那么当时被Wait的线程就重新获取到了锁。
public class Program { public static void Main(string[] args) { LockObj obj = new LockObj(); //注意,这里使用的是同一个资源对象obj Jack jack = new Jack(obj); John john = new John(obj); Thread t1 = new Thread(new ThreadStart(jack.Run)); Thread t2 = new Thread(new ThreadStart(john.Run)); t1.Start(); t1.Name = "Jack"; t2.Start(); t2.Name = "John"; Console.ReadLine(); } } //锁定对象 public class LockObj { } public class Jack { private LockObj obj; public Jack(LockObj obj) { this.obj = obj; } public void Run() { Monitor.Enter(this.obj); Console.WriteLine("{0}:我已进入茅厕。", Thread.CurrentThread.Name); Console.WriteLine("{0}:擦,太臭了,我还是撤!", Thread.CurrentThread.Name); //暂时的释放锁资源 Monitor.Wait(this.obj); Console.WriteLine("{0}:兄弟说的对,我还是进去吧。", Thread.CurrentThread.Name); //唤醒等待队列中的线程 Monitor.Pulse(this.obj); Console.WriteLine("{0}:拉完了,真舒服。", Thread.CurrentThread.Name); Monitor.Exit(this.obj); } } public class John { private LockObj obj; public John(LockObj obj) { this.obj = obj; } public void Run() { Monitor.Enter(this.obj); Console.WriteLine("{0}:直奔茅厕,兄弟,你还是进来吧,小心憋坏了!", Thread.CurrentThread.Name); //唤醒等待队列中的线程 Monitor.Pulse(this.obj); Console.WriteLine("{0}:哗啦啦....", Thread.CurrentThread.Name); //暂时的释放锁资源 Monitor.Wait(this.obj); Console.WriteLine("{0}:拉完了,真舒服。", Thread.CurrentThread.Name); Monitor.Exit(this.obj); } }
时间: 2024-10-12 20:57:57