c# - 锁定的 console.writeline 调用工作不正常

标签 c# multithreading io thread-safety console.writeline

尝试从锁定部分调用 Console.WriteLine,但似乎无法正常工作 - 控制台未锁定。下面是简单应用程序的代码 - 两个线程并行填充一个列表,出于调试目的,我正在打印有关线程工作和新添加元素的信息。

using System;
using System.Threading;
using System.Collections.Generic;

class ThreadSafe
{
    static object SyncRoot = new object();

    static int threadsCount = 0;
    static List<string> list = new List<string>();

    static void Main()
    {
        Thread t1 = new Thread(AddItems);
        Thread t2 = new Thread(AddItems);
        t1.Start();
        t2.Start();

        t1.Join();
        t2.Join();

        PrintItems();

        Console.ReadLine();
    }

    static void PrintItems()
    {
        string[] items;

        Console.WriteLine("Converting list to array...");
        items = list.ToArray();

        Console.WriteLine("Printing array...");
        foreach (string s in items)
            Console.WriteLine(s);
    }

    static void AddItems()
    {
        int threadNo = threadsCount;
        threadsCount++;


        {
            Console.WriteLine("Populating list from {0} item in thread N {1}...", list.Count, threadNo);
            for (int i = 0; i < 50; i++)
            {
                lock (SyncRoot)
                {
                    Console.Write("Population. Thread N {0} is running. ", threadNo);
                    Console.WriteLine("Element N {0} has been added successfully.", list.Count);
                    list.Add("Item " + list.Count);
                }
            }
        }
    }
}

结果:

Populating list from 0 item in thread N 1...
Population. Thread N 1 is running. Element N 0 has been added successfully.
Population. Thread N 1 is running. Element N 1 has been added successfully.
Population. Thread N 1 is running. Element N 2 has been added successfully.
Population. Thread N 1 is running. Element N 3 has been added successfully.
Population. Thread N 1 is running. Element N 4 has been added successfully.
Population. Thread N 1 is running. Element N 5 has been added successfully.
Population. Thread N 1 is running. Element N 6 has been added successfully.
Population. Thread N 1 is running. Element N 7 has been added successfully.
Population. Thread N 1 is running. Element N 8 has been added successfully.
Population. Thread N 1 is running. Element N 9 has been added successfully.
Population. Thread N 1 is running. Element N 10 has been added successfully.
Population. Thread N 1 is running. Element N 11 has been added successfully.
Population. Thread N 1 is running. Element N 12 has been added successfully.
Population. Thread N 1 is running. Element N 13 has been added successfully.
Population. Thread N 1 is running. Element N 14 has been added successfully.
Population. Thread N 1 is running. Element N 15 has been added successfully.
Population. Thread N 1 is running. Populating list from 0 item in thread N 0...
Element N 16 has been added successfully.
Population. Thread N 0 is running. Element N 17 has been added successfully.
Population. Thread N 0 is running. Element N 18 has been added successfully.
Population. Thread N 0 is running. Element N 19 has been added successfully.

在第 15 步和第 16 步之间,新的 first 以某种方式开始运行,并在锁定部分的 Console.Write 和 Console.WriteLine 调用之间输出其内容... Console.WriteLine 确实是非线程安全的吗?还是我做错了什么?

谢谢!

最佳答案

您有 2 个 AddItems 线程,每个线程都进行解锁输出(函数中的第一个)。这种交错是预期的行为。你需要:

  lock (SyncRoot)
  {
    Console.WriteLine("Populating list from {0} item in thread N {1}...", list.Count, threadNo); 
  }

关于c# - 锁定的 console.writeline 调用工作不正常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10499605/

相关文章:

performance - 为什么内存拷贝第一次运行很慢?

java - 创建文件而不根据用户输入创建新文件夹[困惑]

c# - 刷子的径向扫描

C# Linq 列表中的列表

c# - C#中线程安全的可破坏事件触发类

c - 为什么当我在 C 语言的矩阵乘法程序中增加矩阵元素的值时会出现段错误?

javascript - Web Worker 在 HTML5 Canvas 处理中内存不足

java - 通过java Socket传输错误的文件

c# - wpf 将列表框项目绑定(bind)到静态列表

c# - 为什么 WCF 在遇到 302 响应时无法调用 SOAP 服务?