【C#】为什么有可能会被多个线程修改的对象要加线程锁
例1、不用线程锁的情况下,两个线程对同一个变量进行加减操作
static void Main(string[] args)
{
Counter counter = new Counter();
var t1 = new Thread(() => TestCounter(counter));
var t2 = new Thread(() => TestCounter(counter));
t1.Start();
t2.Start(); Thread.Sleep(TimeSpan.FromSeconds());//睡眠3秒,保证t1、t2两个线程都运行完毕
Console.WriteLine(counter.count);
Console.Read();
}

对count变量不断地加1减1,最后count应该为0,但可以看出用两个线程来进行这个操作的时候,往往得到的结果并不是0,出现错误。
例2、使用线程锁,两个线程对同一个变量进行加减操作
static void Main(string[] args)
{
CounterWithLock counterlock = new CounterWithLock();
var t1 = new Thread(() => TestCounter(counterlock));
var t2 = new Thread(() => TestCounter(counterlock));
t1.Start();
t2.Start(); Thread.Sleep(TimeSpan.FromSeconds());//睡眠3秒,保证t1、t2两个线程都运行完毕
Console.WriteLine(counterlock.count);
Console.Read();
}

加上线程锁后,结果正常,因此加上线程锁才能保证不会出错。
例1、例2所用到的类和方法
/// <summary>
/// 对同一个变量进行1000次加减操作
/// </summary>
/// <param name="c"></param>
static void TestCounter(CounterBase c)
{
Console.WriteLine("TestCounter start");
for (int i = ; i < ; i++)
{
c.Increment();
c.Decrement();
}
Console.WriteLine("TestCounter end");
}
abstract class CounterBase
{
public abstract void Increment();
public abstract void Decrement();
} /// <summary>
/// 没有锁
/// </summary>
class Counter : CounterBase
{
public int count { get; private set; } public override void Increment()
{
count ++;
} public override void Decrement()
{
count --;
}
} /// <summary>
/// 加锁
/// </summary>
class CounterWithLock : CounterBase
{
private readonly object locker = new object();
public int count { get; private set; } public override void Increment()
{
lock (locker)
{
count++;
}
} public override void Decrement()
{
lock (locker)
{
count--;
}
}
}
【C#】为什么有可能会被多个线程修改的对象要加线程锁的更多相关文章
- WPF非UI线程中调用App.Current.MainWindow.Dispatcher提示其他线程拥有此对象,无权使用。
大家都知道在WPF中对非UI线程中要处理对UI有关的对象进行操作,一般需要使用委托的方式,代码基本就是下面的写法 App.Current.MainWindow.Dispatcher.Invoke(ne ...
- Python之路-python(paramiko,进程和线程的区别,GIL全局解释器锁,线程)
一.paramiko 二.进程.与线程区别 三.python GIL全局解释器锁 四.线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生 ...
- 浅谈线程池(上):线程池的作用及CLR线程池
原文地址:http://blog.zhaojie.me/2009/07/thread-pool-1-the-goal-and-the-clr-thread-pool.html 线程池是一个重要的概念. ...
- 线程间操作无效: 从不是创建控件“”的线程访问它~~~的解决方法~ 线程间操作无效: 从不是创建控件“Control Name'”的线程访问它问题的解决方案及原理分析
看两个例子,一个是在一个进程里设置另外一个进程中控件的属性.另外一个是在一个进程里获取另外一个进程中控件的属性. 第一个例子 最近,在做一个使用线程控制下载文件的小程序(使用进度条控件显示下载进度)时 ...
- C#中的线程(上)-入门 分类: C# 线程 2015-03-09 10:56 53人阅读 评论(0) 收藏
1. 概述与概念 C#支持通过多线程并行地执行代码,一个线程有它独立的执行路径,能够与其它的线程同时地运行.一个C#程序开始于一个单线程,这个单线程是被CLR和操作系统(也称为"主线 ...
- WPF异常“调用线程无法访问此对象,因为另一个线程拥有该对象 ”
WPF中在对界面进行操作的时候,可能会遇到"调用线程无法访问此对象,因为另一个线程拥有该对象"异常,这是因为WPF中只有UI线程才能操作UI元素,非UI线程要访问UI时就会报异常了 ...
- Qt多线程编程总结(一)(所有GUI对象都是线程不安全的)
Qt对线程提供了支持,基本形式有独立于平台的线程类.线程安全方式的事件传递和一个全局Qt库互斥量允许你可以从不同的线程调用Qt方法. 这个文档是提供给那些对多线程编程有丰富的知识和经验的听众的.推荐阅 ...
- Java并发编程实践读书笔记(1)线程安全性和对象的共享
2.线程的安全性 2.1什么是线程安全 在多个线程访问的时候,程序还能"正确",那就是线程安全的. 无状态(可以理解为没有字段的类)的对象一定是线程安全的. 2.2 原子性 典型的 ...
- [JCIP笔记] (三)如何设计一个线程安全的对象
在当我们谈论线程安全时,我们在谈论什么中,我们讨论了怎样通过Java的synchronize机制去避免几个线程同时访问一个变量时发生问题.忧国忧民的Brian Goetz大神在多年的开发过程中,也悟到 ...
随机推荐
- ubuntu16.04和服务器 caffe 安装
在centos6.X上安装caffe 0.编译安装gcc4.8.5 由于centos6.x中的gcc版本老旧,不支持c++11所以要安装gcc4.8.5,以下是安装教程.参考CentOS 6.4 编译 ...
- react native 之页面跳转
第一章 跳转的实现 1.component 中添加这行代码 <View style={styles.loginmain}> <Text style={styles.loginte ...
- 转:Apache-Tomcat各发布包说明
下载地址:http://tomcat.apache.org/发布包说明: apache-tomcat-[version].zip---------------------------基本发布包.这些发 ...
- VMware Ubuntu 共享文件夹
/**************************************************************************** * VMware Ubuntu 共享文件夹 ...
- 【系列】 2-SAT
bzoj 1997 Planar 题目大意: 给一个存在曼哈顿回路的无向图,求该图是否为平面图 思路: 先把曼哈顿回路提出来,则剩下的边的两个端点若有$ABAB$的形式则这两条边必定一个在环外一个在环 ...
- BZOJ_4609_[Wf2016]Branch Assignment_决策单调性+带权二分
BZOJ_4609_[Wf2016]Branch Assignment_决策单调性+带权二分 Description 要完成一个由s个子项目组成的项目,给b(b>=s)个部门分配,从而把b个部门 ...
- 非旋treap (BZOJ1895)
记个板子,还是挺好用的. #include <bits/stdc++.h> using namespace std; ]; int rt,n,m,l,r,x,A,B,C,t; struct ...
- C++对象的复制——具有指针成员的类的对象的复制
//smartvessel@gmail.com class Table{ Name * p; size_t sz; publish: Table(size_t s = 15){p = new Name ...
- 在头文件#pragma comment(lib,"glaux.lib");编译器提示waring C4081: 应输入“newline“
在头文件#pragma comment(lib,"glaux.lib");编译器提示waring C4081: 应输入“newline“ #行不能加分号的
- 03_主线程联网问题&ANR&子线程不能修改UI
如果不使用HAXM,恐怕网页源码查看器无法获取servlet的源码.初步猜测是安卓模拟器运行速度太慢了.如果CPU不支持VT-x的话,HAXM是安装不上的.所以可以先开启VT-x. 可以参考几篇文章h ...