C#多线程学习笔记(三)

简介: 刚刚把前两天的笔记整理完了,发现做笔记可以加深印象。要坚持做下去,可以学到一些细节的东西。a.今天学到一个非常试用的lock  语法:   lock(expression) statement_block    expression代表你希望跟踪的对象,通常是对象引用。
刚刚把前两天的笔记整理完了,发现做笔记可以加深印象。要坚持做下去,可以学到一些细节的东西。

a.今天学到一个非常试用的lock
  语法:
   lock(expression) statement_block
   expression代表你希望跟踪的对象,通常是对象引用。一般地,如果你想保护一个类的实例,你可以使用this;如果你希望保护一个静态变量(如互斥代码段在一个静态方法内部),一般使用类名就可以了。而statement_block就是互斥段的代码,这段代码在一个时刻内只可能被一个线程执行。
img_a6339ee3e57d1d52bc7d02b338e15a60.gif using  System;
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
using  System.Collections.Generic;
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
using  System.Text;
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
using  System.Threading;
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
img_a6339ee3e57d1d52bc7d02b338e15a60.gif
namespace  LockThread
img_405b18b4b6584ae338e0f6ecaf736533.gifimg_1c53668bcee393edac0d7b3b3daff1ae.gif
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif {
img_33d02437d135341f0800e3d415312ae8.gif    
internal class Account
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif    
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif        
int balance;
img_33d02437d135341f0800e3d415312ae8.gif        Random r 
= new Random();
img_33d02437d135341f0800e3d415312ae8.gif        
internal Account(int _initial)
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif        
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif            balance 
= _initial;
img_105a1e124122b2abcee4ea8e9f5108f3.gif        }

img_33d02437d135341f0800e3d415312ae8.gif
img_33d02437d135341f0800e3d415312ae8.gif        
internal int Withdraw(int _amount)
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif        
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif            
if(balance < 0)
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif            
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif                
//如果balance<0则抛出异常
img_33d02437d135341f0800e3d415312ae8.gif
                throw new Exception("Negative Balance");
img_105a1e124122b2abcee4ea8e9f5108f3.gif            }

img_33d02437d135341f0800e3d415312ae8.gif            
//下面的代码保证在当前线程修改balance的值完成之前
img_33d02437d135341f0800e3d415312ae8.gif            
//不会有其他线程也执行这段代码来修改balance的值
img_33d02437d135341f0800e3d415312ae8.gif            
//因此,balance的值是不可能小于0的
img_33d02437d135341f0800e3d415312ae8.gif
            lock(this)
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif            
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif                Console.WriteLine(
"Current Thread:"+Thread.CurrentThread.Name);
img_33d02437d135341f0800e3d415312ae8.gif                
//如果没有lock关键字的保护,那么可能在执行完if的条件判断之后
img_33d02437d135341f0800e3d415312ae8.gif            
//另外一个线程却执行了balance=balance-amount修改了balance的值
img_33d02437d135341f0800e3d415312ae8.gif            
//而这个修改对这个线程是不可见的,所以可能导致这时if的条件已经不成立了
img_33d02437d135341f0800e3d415312ae8.gif            
//但是,这个线程却继续执行balance=balance-amount,所以导致balance可能小于0
img_33d02437d135341f0800e3d415312ae8.gif
                if(balance >= _amount)
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif                
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif                    Thread.Sleep(
5);
img_33d02437d135341f0800e3d415312ae8.gif                    balance 
= balance -_amount;
img_33d02437d135341f0800e3d415312ae8.gif                    
return _amount;
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif                }
 elseimg_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif                    
return 0;//处理事务被拒绝
img_105a1e124122b2abcee4ea8e9f5108f3.gif
                }

img_105a1e124122b2abcee4ea8e9f5108f3.gif            }

img_105a1e124122b2abcee4ea8e9f5108f3.gif        }

img_33d02437d135341f0800e3d415312ae8.gif        
internal void DoTransactions()
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif        
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif            
for(int i = 0;i<100; i++)
img_33d02437d135341f0800e3d415312ae8.gif                Withdraw(r.Next(
-50100));
img_105a1e124122b2abcee4ea8e9f5108f3.gif        }

img_33d02437d135341f0800e3d415312ae8.gif
img_105a1e124122b2abcee4ea8e9f5108f3.gif  }

img_33d02437d135341f0800e3d415312ae8.gif 
img_33d02437d135341f0800e3d415312ae8.gif
img_33d02437d135341f0800e3d415312ae8.gif    
class Program
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif    
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif        
static internal Thread[] threads = new Thread[10];
img_33d02437d135341f0800e3d415312ae8.gif        
static void Main(string[] args)
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif        
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif            Account acc 
= new Account(0);
img_33d02437d135341f0800e3d415312ae8.gif            
for (int i = 0; i < 10; i++)
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif            
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif                Thread t 
= new Thread(new ThreadStart(acc.DoTransactions));
img_33d02437d135341f0800e3d415312ae8.gif                t.Name 
= i.ToString();
img_33d02437d135341f0800e3d415312ae8.gif                threads[i] 
= t;
img_105a1e124122b2abcee4ea8e9f5108f3.gif            }

img_33d02437d135341f0800e3d415312ae8.gif
img_33d02437d135341f0800e3d415312ae8.gif            
for (int i = 0; i < 10; i++)
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif            
img_a76e9bb6ed00cf1c9c9f4ee2f04b558b.gif{
img_33d02437d135341f0800e3d415312ae8.gif                threads[i].Start();
img_105a1e124122b2abcee4ea8e9f5108f3.gif            }

img_33d02437d135341f0800e3d415312ae8.gif            Console.ReadLine();
img_105a1e124122b2abcee4ea8e9f5108f3.gif        }

img_105a1e124122b2abcee4ea8e9f5108f3.gif    }

img_05dd8d549cff04457a6366b0a7c9352a.gif}

img_a6339ee3e57d1d52bc7d02b338e15a60.gif


b.还有一个Moniter对象是用来监视对象的,
......
Queue oQueue=new Queue();
......
Monitor.Enter(oQueue);
......//现在oQueue对象只能被当前线程操纵了
Monitor.Exit(oQueue);//释放锁

上面表示oQueue这个对象只有一个线程可以操纵,只有当Mointor.Exit才可以被其它线程所操纵
目录
相关文章
|
3月前
|
编解码 数据安全/隐私保护 计算机视觉
Opencv学习笔记(十):同步和异步(多线程)操作打开海康摄像头
如何使用OpenCV进行同步和异步操作来打开海康摄像头,并提供了相关的代码示例。
137 1
Opencv学习笔记(十):同步和异步(多线程)操作打开海康摄像头
|
5月前
|
数据采集 XML JavaScript
C# 中 ScrapySharp 的多线程下载策略
C# 中 ScrapySharp 的多线程下载策略
|
3月前
FFmpeg学习笔记(二):多线程rtsp推流和ffplay拉流操作,并储存为多路avi格式的视频
这篇博客主要介绍了如何使用FFmpeg进行多线程RTSP推流和ffplay拉流操作,以及如何将视频流保存为多路AVI格式的视频文件。
405 0
|
3月前
|
C#
C#中的数组型参数学习笔记
C#中的数组型参数学习笔记
32 0
|
5月前
|
调度
多线程学习笔记
这篇文章是多线程学习笔记,涵盖了线程与进程的概念、多线程实现方式、线程状态、线程同步与不安全示例、死锁问题以及生产者与消费者问题等多线程编程的关键知识点。
多线程学习笔记
|
4月前
|
安全 数据库连接 API
C#一分钟浅谈:多线程编程入门
在现代软件开发中,多线程编程对于提升程序响应性和执行效率至关重要。本文从基础概念入手,详细探讨了C#中的多线程技术,包括线程创建、管理及常见问题的解决策略,如线程安全、死锁和资源泄露等,并通过具体示例帮助读者理解和应用这些技巧,适合初学者快速掌握C#多线程编程。
89 0
|
5月前
|
安全 C# 开发者
【C# 多线程编程陷阱揭秘】:小心!那些让你的程序瞬间崩溃的多线程数据同步异常问题,看完这篇你就能轻松应对!
【8月更文挑战第18天】多线程编程对现代软件开发至关重要,特别是在追求高性能和响应性方面。然而,它也带来了数据同步异常等挑战。本文通过一个简单的计数器示例展示了当多个线程无序地访问共享资源时可能出现的问题,并介绍了如何使用 `lock` 语句来确保线程安全。此外,还提到了其他同步工具如 `Monitor` 和 `Semaphore`,帮助开发者实现更高效的数据同步策略,以达到既保证数据一致性又维持良好性能的目标。
66 0
|
7月前
|
并行计算 算法 C#
C# Mandelbrot和Julia分形图像生成程序更新到2010-9-14版 支持多线程计算 多核处理器
此文档是一个关于分形图像生成器的介绍,作者分享了个人开发的M-J算法集成及色彩创新,包括源代码和历史版本。作者欢迎有兴趣的读者留言交流,并提供了邮箱(delacroix_xu@sina.com)以分享资源。文中还展示了程序的发展历程,如增加了真彩色效果、圈选放大、历史记录等功能,并分享了几幅精美的分形图像。此外,还提到了程序的新特性,如导入ini文件批量输出图像和更新一批图片的功能。文档末尾附有多张程序生成的高分辨率分形图像示例。
|
7月前
|
大数据 C#
C#实现多线程的几种方式
C#实现多线程的几种方式