线程问题----线程争用(加锁)

如果在线程之间共享数据,则可能会出现线程争用的问题

1,局一个线程争用的例子:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace ConsoleApplication6
{
    class Program
    {
        static void Main(string[] args)
        {
            SampleTask st = new SampleTask();
            StateObject so = new StateObject();
            //开启20个任务,每个任务循环执行StateObject类的ChangeState方法
            for (int i = 0; i < 20; i++)
            {
                new Task(st.RaceCondition, so).Start();
            }
            Console.WriteLine("运行完成");
            Console.ReadLine();
        }
    }
    //简单的任务类
    class SampleTask
    {
        public void RaceCondition(object o)
        {
            Trace.Assert(o is StateObject, "只能传递StateObject对象");
            StateObject s = o as StateObject;
            int i = 0;
            //单个任务循环执行StateObject类的ChangeState方法
            while (true)
            {
                s.ChangeState(++i);
            }
        }
    }
    //状态类
    //如果state为5,则加1,后面跟着检查state,如果不为6,就出现了争用。
    class StateObject
    {
        int state = 5;
        public void ChangeState(int loop)
        {
            if (state == 5)
            {
                state++;
                //为false说明出现争用,则程序断言(弹出框)
                Trace.Assert(state == 6, "在循环了" + loop.ToString() + "次后出现了争用");
            }
            state = 5;
        }
    }
   
}

2,解决办法:

①:使用lock锁定共享的s变量

    //简单的任务类
    class SampleTask
    {
        public void RaceCondition(object o)
        {
            Trace.Assert(o is StateObject, "只能传递StateObject对象");
            StateObject s = o as StateObject;
            
            int i = 0;
            //单个任务循环执行StateObject类的ChangeState方法
            while (true)
            {
                //使用lock锁定共享的s变量
                lock (s)
                {
                    s.ChangeState(++i);
                }
            }
        }
    }

②:将共享对象设置为线程安全的对象

    //状态类
    //如果state为5,则加1,后面跟着检查state,如果不为6,就出现了争用。
    class StateObject
    {
        int state = 5;
        public void ChangeState(int loop)
        {
            //将共享对象设置为线程安全的对象
            lock (this)
            {
                if (state == 5)
                {
                    state++;
                    //为false说明出现争用,则程序断言(弹出框)
                    Trace.Assert(state == 6, "在循环了" + loop.ToString() + "次后出现了争用");
                }
                state = 5;
            }
        }
    }
时间: 2024-08-07 19:18:34

线程问题----线程争用(加锁)的相关文章

C#中的线程(二) 线程同步基础

1.同步要领 下面的表格列展了.NET对协调或同步线程动作的可用的工具:                       简易阻止方法 构成 目的 Sleep 阻止给定的时间周期 Join 等待另一个线程完成                       锁系统 构成 目的 跨进程? 速度 lock 确保只有一个线程访问某个资源或某段代码. 否 快 Mutex 确保只有一个线程访问某个资源或某段代码.可被用于防止一个程序的多个实例同时运行. 是 中等 Semaphore 确保不超过指定数目的线程访问某

线程同步--线程间通信

一.线程同步 线程的同步方法跟其他系统下类似,我们可以用原子操作,可以用 mutex,lock 等. iOS 的原子操作函数是以 OSAtomic 开头的,比如:OSAtomicAdd32, OSAtomicOr32 等等.这些函数可以直接使用,因为它 们是原子操作. iOS 中的 mutex 对应的是 NSLock,它遵循 NSLooking 协议,我们可以使用 lock, tryLock, lockBeforeData:来加锁,用 unLock 来解锁.使用示例: BOOL moreToDo

线程基础--线程控制

3.  线程控制 1). 线程属性 目标:可以设置 线程的 detached/join 状态,线程栈的大小和最低地址等属性. detached/join 状态的区别: 当线程处于 分离状态(detached)时,线程结束时,os立即回收资源.主线程不可以调用pthread_join获取线程退出时的返回值. 当线程处于 未分离状态(join)时,线程结束时,主线程 调用pthread_join获取线程退出时的返回值, 随后释放该线程资源. a)数据类型 pthread_attr_t b)初始化及释

java---多线程及线程的概念

如果对什么是线程.什么是进程仍存有疑惑,请先Google之,因为这两个概念不在本文的范围之内. 用多线程只有一个目的,那就是更好的利用cpu的资源,因为所有的多线程代码都可以用单线程来实现.说这个话其实只有一半对,因为反应"多角色"的程序代码,最起码每个角色要给他一个线程吧,否则连实际场景都无法模拟,当然也没法说能用单线程来实现:比如最常见的"生产者,消费者模型". 很多人都对其中的一些概念不够明确,如同步.并发等等,让我们先建立一个数据字典,以免产生误会. 多线程

python开发线程:线程&amp;守护线程&amp;全局解释器锁

一 threading模块介绍 multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性,因而不再详细介绍 官网链接:https://docs.python.org/3/library/threading.html?highlight=threading# 二 开启线程的两种方式 #方式一 from threading import Thread import time def sayhi(name): time.sleep(2) print('%s

iOS中NSThread(主线程,子线程)

#import "AppDelegate.h" @interface AppDelegate () { NSInteger _totalTickests; } @property (nonatomic, retain) NSLock *lock; @end @implementation AppDelegate - (void)task1 { NSLog(@"当前线程:%@,是否是主线程:%d",[NSThread currentThread],[[NSThread

Linux互斥与同步应用(一):posix线程及线程间互斥

[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet 或 .../gentleliu,文章仅供学习交流,请勿用于商业用途] 有了进程的概念,为何还要使用线程呢? 首先,回忆一下上一个系列我们讲到的IPC,各个进程之间具有独立的内存空间,要进行数据的传递只能通过通信的方式进行,这种方式不仅费时,而且很不方便.而同一个进程下的线程是共享全局内存的,所以一个线程的数据可以在另一个线程中直接使用,及快捷又方便. 其次,在Linux系统下,启动一个新的进程必须分配给它独立的地

基础学习day12--多线程一线程之间的通信和常用方法

一.线程之间的通信 1.1.线程之间的通信方法 多个线程在处理统一资源,但是任务却不同,这时候就需要线程间通信.    等待/唤醒机制涉及的方法:    1. wait():让线程处于冻结状态,被wait的线程会被存储到线程池中.    2. notify():唤醒线程池中的一个线程(任何一个都有可能).    3. notifyAll():唤醒线程池中的所有线程.  备注    1.这些方法都必须定义在同步中,因为这些方法是用于操作线程状态的方法.    2.必须要明确到底操作的是哪个锁上的线

java中的进程,线程,线程池总结

1.线程与进程 进程 狭义上讲:正在执行的程序,由线程组成,可包含多个线程在运行. 广义上讲:进程是一个具有一定独立功能的程序有关于某个数据集合的一次运行的活动.它可以申请或者拥有系统资源,是一个动态的概念. 进程的概念主要两点:1.进程是一个实体,每一个进程都有自己的地址空间,一般情况下包括文本区域,数据区和堆栈. 线程 为进程中执行的程序片段. 一个线程由线程ID,当前指令针,寄存器和堆栈组成,另外线程是进程的实体,是被系统独立调试的分派的基本单元. 线程是程序中一个单一的顺序控制流程.进程

JAVA线程与线程、进程与进程间通信

I.线程与线程间通信 一.多线程间通信方式: 1.共享变量 2.wait/notify机制 3.Lock/Condition机制 4.管道 二.共享变量 线程间发送信号的一个简单方式是在共享对象的变量里设置信号值.线程A在一个同步块里设置boolean型成员变量hasDataToProcess为true,线程B也在同步块里读取hasDataToProcess这个成员变量.这个简单的例子使用了一个持有信号的对象,并提供了set和check方法: public class MySignal{ pro