首页 / C# / c# – 这段代码实际上是线程安全的吗?
c# – 这段代码实际上是线程安全的吗?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – 这段代码实际上是线程安全的吗?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2185字,纯文字阅读大概需要4分钟。
内容图文
![c# – 这段代码实际上是线程安全的吗?](/upload/InfoBanner/zyjiaocheng/787/40a9de5ece1a4a33bd2663997e2f26b7.jpg)
我有一个关于以下代码段的问题,我在Microsoft的C#教程网页上找到了该代码段.在代码中,它们提供了任务演示.在事件处理程序中,他们创建一个更新未受保护的集合的任务.
这段代码是线程安全的吗?在我看来,事实并非如此.使这段代码线程安全的最佳方法是什么?
private ArrayList students = new ArrayList();
private void btnCreateStudent_Click(object sender, RoutedEventArgs e)
{
Student newStudent = new Student();
newStudent.FirstName = txtFirstName.Text;
newStudent.LastName = txtLastName.Text;
newStudent.City = txtCity.Text;
ClearForm();
Task task1 = new Task(() => AddToCollection(newStudent));
task1.Start();
ClearForm();
}
private void AddToCollection(Student student)
{
Thread.Sleep(5000);
students.Add(student);
int count = students.Count;
MessageBox.Show("Student created successfully. Collection contains " + count.ToString() + " Student(s).");
}
我不同意以下声明
students.Add(student);
我认为它应该受到锁的保护.
解决方法:
Is this code actually thread-safe?
不,这不对.
根据documentation,ArrayList实例不支持并发修改,除非它是由Synchronized方法返回的,并不是这里的情况.
虽然可能并不明显,但在您的示例中可能会发生并发修改. Task被排队到ThreadPool,它将由来自此池的某个线程运行.如果用户双击btnCreateStudent将创建两个任务,并且由于Thread.Sleep不是非常精确,无论如何,任务不必立即执行(例如ThreadPool队列可能已满),因此有两个任务,虽然预定在不同时间,但可能同时执行.
What is the best way to make this code thread-safe?
这取决于你所说的“最好的”.
第一个解决方案是使用Synchronized方法创建ArrayList.
private ArrayList students = ArrayList.Synchronized(new ArrayList());
但是你仍然需要使用锁来枚举这个列表.
Enumerating through a collection is intrinsically not a thread-safe
procedure. Even when a collection is synchronized, other threads can
still modify the collection, which causes the enumerator to throw an
exception. To guarantee thread safety during enumeration, you can
either lock the collection during the entire enumeration or catch the
exceptions resulting from changes made by other threads.
另一种解决方案是使用List<T>并在访问集合的任何地方添加锁.列表< T>优于ArrayList,因为它包含元素类型,因此您不必在读取时强制转换它们,或者您不会意外地将不兼容的类型添加到集合中.
如果您不关心物品的顺序,那么您应该使用ConcurrentBag<T>,它不需要任何锁定.
内容总结
以上是互联网集市为您收集整理的c# – 这段代码实际上是线程安全的吗?全部内容,希望文章能够帮你解决c# – 这段代码实际上是线程安全的吗?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。