惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

AI
AI
TaoSecurity Blog
TaoSecurity Blog
H
Heimdal Security Blog
Help Net Security
Help Net Security
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Microsoft Azure Blog
Microsoft Azure Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Google DeepMind News
Google DeepMind News
爱范儿
爱范儿
The Cloudflare Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
人人都是产品经理
人人都是产品经理
大猫的无限游戏
大猫的无限游戏
N
News | PayPal Newsroom
V2EX - 技术
V2EX - 技术
博客园 - 【当耐特】
D
Darknet – Hacking Tools, Hacker News & Cyber Security
S
Secure Thoughts
C
CERT Recently Published Vulnerability Notes
罗磊的独立博客
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
P
Privacy & Cybersecurity Law Blog
有赞技术团队
有赞技术团队
S
Schneier on Security
S
SegmentFault 最新的问题
Google Online Security Blog
Google Online Security Blog
H
Hacker News: Front Page
The Last Watchdog
The Last Watchdog
Schneier on Security
Schneier on Security
PCI Perspectives
PCI Perspectives
IT之家
IT之家
Project Zero
Project Zero
博客园 - 司徒正美
P
Privacy International News Feed
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Jina AI
Jina AI
Security Latest
Security Latest
Hacker News - Newest:
Hacker News - Newest: "LLM"
腾讯CDC
C
CXSECURITY Database RSS Feed - CXSecurity.com
阮一峰的网络日志
阮一峰的网络日志
C
Check Point Blog
aimingoo的专栏
aimingoo的专栏
V
Vulnerabilities – Threatpost
W
WeLiveSecurity
NISL@THU
NISL@THU
Webroot Blog
Webroot Blog
N
Netflix TechBlog - Medium
L
Lohrmann on Cybersecurity

博客园 - 言午

Nopcommerce 二次开发2 Admin Nopcommerce 二次开发1 基础 Nopcommerce 二次开发2 WEB Nopcommerce 二次开发0 sqlce中不支持sp_rename修改表名 C#读取Excel遇到无法读取的解决方法 狼奔代码生成器 银行账户类 累 interface 抽象类 抽象方法 Message 类的继承 多态(虚方法) 事件event 委托 代理 索引! 第五周作业 第四周作业 考试! 线程安全 一
线程安全 二
言午 · 2011-11-15 · via 博客园 - 言午

using System;
using System.Threading;

abstract class Counter
{
    protected int count = 0;

    public abstract int Read(int threadNum);
    public abstract void Increment(int threadNum); 
}

// Note that the instance variable count is shared between the two methods Read
// and Increment. Threads concurrently executing one or both of these methods can
// interfere with each other unless action is taken to synchronize access

class CounterUnsafe : Counter
{
    public override int Read(int threadNum) 
    {
        // following code is not thread-safe and has a race condition
        try 
        {
            Console.WriteLine(
                "Start Resource reading (Thread={0})count: {1}", threadNum, count);
            Thread.Sleep(250);
            Console.WriteLine(
                "Stop  Resource reading (Thread={0}) count: {1}", threadNum, count);
            return count;
        }
        finally 
        {
        }
    }

    public override void Increment(int threadNum) 
    {
        // following code is not thread-safe and has a race condition
        try 
        {
            Console.WriteLine(
                "Start Resource writing (Thread={0}) count: {1}", threadNum, count);
            // the following four lines simulate count++ with a very large
            
// window of time between count being read and being incremented.
            
// This large window ensures that the race condition will create
            
// errors often when the code is accessed concurrently by multiple threads.
            int tempCount = count;
            Thread.Sleep(1000);
            tempCount++;
            count = tempCount;
            Console.WriteLine(
                "Stop  Resource writing (Thread={0}) count: {1}", threadNum, count);
        }
        finally 
        {
        }
    }
}

class CounterUsingInterlocked : Counter
{
    public override int Read(int threadNum) 
    {
        try 
        {
            // following is thread safe but since Increments can occur during
            
//  this method, the value of count can change between the start 
            
//  of the method and its return/end, if this is a problem
            
//  you need to use manual locks or a synchronized context.
            Console.WriteLine(
                "Start Resource reading (Thread={0})count: {1}", threadNum, count);
            Thread.Sleep(250);
            Console.WriteLine(
                "Stop  Resource reading (Thread={0}) count: {1}", threadNum, count);
            return count;
        }
        finally 
        {
        }
    }

    public override void Increment(int threadNum) 
    {
        // ...
        
// method code that doesn't require exclusive access 
        try 
        {
            Console.WriteLine(
                "Start Resource writing (Thread={0}) count: {1}", threadNum, count);
            // Note that count++ is not  an atomic operation and therefore not thread-safe.
            
//  With count++ there would be a window of time between reading the value count and 
            
//  incrementing the value of count during which time another thread could execute and
            
//  also read and/or change the value of count. Even thought this window
            
//  is much smaller than with the CounterUnsafe methods this non atomic operation
            
//  still results in a race condition where an increment can be lost.
            
// To make the increment of count thread-safe we use an atomic Interlocked.Increment call.
            int tempCount = Interlocked.Increment(ref count);
            Console.WriteLine(
                "Stop Resource writing (Thread={0}) count: {1}", threadNum, tempCount);
        }
        finally 
        {
        }
    }
}

class CounterUsingLock : Counter
{
    public override int Read(int threadNum) 
    {
        // ...
        
// method code that doesn't require exclusive access 
        lock(this)
        {
            Console.WriteLine(
                "Start Resource reading (Thread={0})count: {1}", threadNum, count);
            Thread.Sleep(250);
            Console.WriteLine(
                "Stop Resource reading (Thread={0}) count: {1}", threadNum, count);
            return count;
        }
    }

    public override void Increment(int threadNum) 
    {
        // ...
        
// method code that doesn't require exclusive access 
        lock(this)
        {
            Console.WriteLine(
                "Start Resource writing (Thread={0}) count: {1}", threadNum, count);
            int tempCount = count;
            Thread.Sleep(1000);
            tempCount++;
            count = tempCount;
            Console.WriteLine(
                "Stop Resource writing (Thread={0}) count: {1}", threadNum, count);
        }
        // rest of method code that doesn't require exclusive access
    }
}

class CounterUsingMutex : Counter
{
    Mutex m = new Mutex(); 

    public override int Read(int threadNum) 
    {
        // ...
        
// method code that doesn't require exclusive access 
        m.WaitOne();
        try 
        {
            Console.WriteLine(
                "Start Resource reading (Thread={0})count: {1}", threadNum, count);
            Thread.Sleep(250);
            Console.WriteLine(
                "Stop Resource reading (Thread={0}) count: {1}", threadNum, count);
            return count;
        }
        finally 
        {
            m.ReleaseMutex();
        }
    }

    public override void Increment(int threadNum) 
    {
        // ...
        
// method code that doesn't require exclusive access 
        m.WaitOne();
        try 
        {
            Console.WriteLine(
                "Start Resource writing (Thread={0}) count: {1}", threadNum, count);
            int tempCount = count;
            Thread.Sleep(1000);
            tempCount++;
            count = tempCount;
            Console.WriteLine(
                "Stop Resource writing (Thread={0}) count: {1}", threadNum, count);
        }
        finally 
        {
            m.ReleaseMutex();
        }
        // rest of method code that doesn't require exclusive access
    }
}

class CounterUsingReaderWriterLock : Counter
{
    ReaderWriterLock rwl = new ReaderWriterLock();

    public override int Read(int threadNum) 
    {
        // ...
        
// method code that doesn't require exclusive access 
        rwl.AcquireReaderLock(Timeout.Infinite);
        try 
        {
            Console.WriteLine(
             "Start Resource reading (Thread={0})count: {1}", threadNum, count);
            Thread.Sleep(250);
            Console.WriteLine(
             "Stop Resource reading (Thread={0}) count: {1}", threadNum, count);
            return count;
        }
        finally 
        {
            rwl.ReleaseReaderLock();
        }
    }

    public override void Increment(int threadNum) 
    {
        // ...
        
// method code that doesn't require exclusive access 
        rwl.AcquireWriterLock(Timeout.Infinite);
        try 
        {
            Console.WriteLine(
             "Start Resource writing (Thread={0}) count: {1}", threadNum, count);
            int tempCount = count;
            Thread.Sleep(1000);
            tempCount++;
            count = tempCount;
            Console.WriteLine(
             "Stop  Resource writing (Thread={0}) count: {1}", threadNum, count);
        }
        finally 
        {
            rwl.ReleaseWriterLock();
        }
        // rest of method code that doesn't require exclusive access
    }
}

class App 
{
    static Counter counter = null;
    static int totalNumberOfAsyncOps = 10;
    static int numAsyncOps = totalNumberOfAsyncOps;
    static AutoResetEvent asyncOpsAreDone = new AutoResetEvent(false);

    public static void Main() 
    {
        Console.WriteLine("\n\nUnsafe test:");
        asyncOpsAreDone.Reset();
        numAsyncOps = totalNumberOfAsyncOps;
        counter = new CounterUnsafe();
        for (int threadNum = 0; threadNum < numAsyncOps; threadNum++) 
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(UpdateResource), threadNum);
        }
        asyncOpsAreDone.WaitOne();
        Console.WriteLine("All Unsafe threads have completed.");
        
        
        Console.WriteLine("\n\nInterlocked test:");
        asyncOpsAreDone.Reset();
        numAsyncOps = totalNumberOfAsyncOps;
        counter = new CounterUsingInterlocked();
        for (int threadNum = 0; threadNum < totalNumberOfAsyncOps; threadNum++) 
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(UpdateResource), threadNum);
        }
        asyncOpsAreDone.WaitOne();
        Console.WriteLine("All Interlocked threads have completed.");

        Console.WriteLine("\n\nLock test:");
        asyncOpsAreDone.Reset();
        numAsyncOps = totalNumberOfAsyncOps;
        counter = new CounterUsingLock();
        for (int threadNum = 0; threadNum < numAsyncOps; threadNum++) 
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(UpdateResource), threadNum);
        }
        asyncOpsAreDone.WaitOne();
        Console.WriteLine("All Lock threads have completed.");

        Console.WriteLine("\n\nMutex test:");
        asyncOpsAreDone.Reset();
        numAsyncOps = totalNumberOfAsyncOps;
        counter = new CounterUsingMutex();
        for (int threadNum = 0; threadNum < numAsyncOps; threadNum++) 
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(UpdateResource), threadNum);
        }
        asyncOpsAreDone.WaitOne();
        Console.WriteLine("All Mutex threads have completed.");

    
        asyncOpsAreDone.Reset();
        numAsyncOps = totalNumberOfAsyncOps;
        counter = new CounterUsingReaderWriterLock();
        Console.WriteLine("\n\nReadWriteLock test:");
        for (int threadNum = 0; threadNum < numAsyncOps; threadNum++) 
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(UpdateResource), threadNum);
        }
        asyncOpsAreDone.WaitOne();
        Console.WriteLine("All ReadWriteLock threads have completed.");
        
    }

    // The callback method's signature MUST match that of a System.Threading.TimerCallback 
    
// delegate (it takes an Object parameter and returns void)
    static void UpdateResource(Object state) 
    {
        int threadNum = (int) state;
        if ((threadNum % 2) != 0) counter.Read(threadNum);
        else counter.Increment(threadNum);

        if (( Interlocked.Decrement(ref numAsyncOps)) == 0)
            asyncOpsAreDone.Set();
    }
}