C#多线程学习笔记
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication19
{
class Program
{
//创建一个新线程
//static void Main(string[] args)
//{
// Thread t = new Thread(WriteY);//创建新线程
// t.Start();//启动新线程,执行writeY();
// for (int i = 0; i < 1000; i++) Console.Write("x");
// Console.ReadKey();
//}
//static void WriteY()
//{
// for (int i = 0; i < 1000; i++) Console.Write("y");
//}
/*
CLR 为每个线程分配各自独立的栈空间,因此局部变量是独立的。在下面的例子中,我们定义一个拥有局部变量的方法,
* 然后在主线程和新创建的线程中同时执行该方法。
*/
//static void Main(string[] args)
//{
// new Thread(Go).Start();
// Go();
// Console.ReadKey();
//}
//static void Go()
//{
// for (int i = 0; i < 5; i++)
// Console.Write('?');
//}
//线程可以通过对同一对象的引用来共享数据。
//由于两个线程是调用了同一个的ThreadTest实例上的Go(),它们共享了done字段
//,因此输出结果是一次 “ Done “,而不是两次。
//bool done;
//static void Main(string[] args)
//{
// Program tt = new Program();
// new Thread(tt.Go).Start();
// tt.Go();
// Console.ReadKey();
//}
//void Go()
//{
// if (!done) { done = true; Console.WriteLine("Done"); }
//}
//静态字段提供了另一种在线程间共享数据的方式,以下是一个静态的done字段的例子:
//static bool done;
//static void Main(string[] args)
//{
// new Thread(Go).Start();
// Go();
// Console.ReadKey();
//}
//static void Go()
//{
// if (!done) { done = true; Console.WriteLine("Done"); }
//}
/*
需要在读写公共字段时,获得一个排它锁(互斥锁,exclusive lock )。C# 提供了lock来达到这个目的:
* 当两个线程同时争夺一个锁的时候(例子中的locker),一个线程等待,或者说阻塞,直到锁变为可用。
* 这样就确保了在同一时刻只有一个线程能进入临界区(critical section,不允许并发执行的代码)
* ,所以 “ Done “ 只被打印了一次。像这种用来避免在多线程下的不确定性的方式被称为线程安全(thread-safe)。
*/
//static bool done;
//static readonly object locker = new object();
//static void Main(string[] args)
//{
// new Thread(Go).Start();
// Go();
// Console.ReadKey();
//}
//static void Go()
//{
// lock (locker)
// {
// if (!done) { Console.WriteLine("Done"); done = true; }
// }
//}
/*
可以通过调用线程的Join方法来等待另一个线程结束
当使用Sleep或Join等待时,线程是阻塞(blocked)状态,因此不会消耗 CPU 资源
Thread.Sleep(0)会立即释放当前的时间片,将 CPU 资源出让给其它线程。Framework 4.0 新的Thread.Yield()方法与其相同,除了它只会出让给运行在相同处理器核心上的其它线程。
Sleep(0)和Yield在调整代码性能时偶尔有用,它也是一个很好的诊断工具,
* 可以用于找出线程安全(thread safety)的问题。如果在你代码的任意位置插入Thread.Yield()会影响到程序
* ,基本可以确定存在 bug。
*/
//static void Main(string[] args)
//{
// Thread t = new Thread(Go);
// t.Start();
// t.Join();
// Thread.Sleep(TimeSpan.FromSeconds(1));
// Console.WriteLine("Thread t has ended");
// Console.ReadKey();
//}
//static void Go()
//{
// for (int i = 0; i < 1000; i++)
// Console.Write("y");
//}
/*使用Thread类的构造方法来创建线程,
通过传递ThreadStart委托来指明线程从哪里开始运行,
* 下面是ThreadStart委托的定义:
*/
//static void Go()
//{
// Console.WriteLine("hello!");
//}
//static void Main()
//{
// Thread t = new Thread( new ThreadStart(Go));
// t.Start();
// Go();
// Console.ReadKey();
//}
/*
另一个方法是向Thread的Start方法传递参数
*/
//static void Main()
//{
// Thread t = new Thread(Print);
// t.Start("Hello from t!");
// Console.ReadKey();
//}
//static void Print(object messageObj)
//{
// string message = (string)messageObj; // 需要强制类型转换
// Console.WriteLine(message);
//}
/*
每一个线程都有一个 Name 属性,我们可以设置它以便于调试
* 。这在 Visual Studio 中非常有用,因为线程的名字会显示在线程窗口(Threads Window)与调试位置(Debug Location)工具栏上。
* 线程的名字只能设置一次,以后尝试修改会抛出异常。
静态的Thread.CurrentThread属性会返回当前执行的线程。在下面的例子中,我们设置主线程的名字:
*/
//static void Main()
//{
// Thread.CurrentThread.Name = "main";
// Thread worker = new Thread(Go);
// worker.Name = "worker";
// worker.Start();
// Go();
// Console.ReadKey();
//}
//static void Go()
//{
// Console.WriteLine("hello from" + Thread.CurrentThread.Name);
//}
/*
默认情况下,显式创建的线程都是前台线程(foreground threads)。
* 只要有一个前台线程在运行,程序就可以保持存活,而后台线程(background threads)并不能保持程序存活。
* 当一个程序中所有前台线程停止运行时,
* 仍在运行的所有后台线程会被强制终止。
* 可以通过线程的IsBackground属性来查询或修改线程的前后台状态
在退出程序时可以显式的等待这些后台线程结束。有两种方法可以实现:
如果是自己创建的线程,在线程上调用Join方法。
如果是使用线程池线程,使用事件等待句柄。
* */
//static void Main(string[] args)
//{
// Thread worker = new Thread(() => Console.ReadLine());
// if (args.Length > 0) worker.IsBackground = true;
// worker.Start();
// Console.ReadKey();
//}
/*
如果是使用 .NET Framework 4.0 以前的版本,
* 则不能使用任务并行库。
* 你必须通过一种旧的构造使用线程池:ThreadPool.QueueUserWorkItem与异步委托。
* 这两者之间的不同在于异步委托可以让你从线程中返回数据,
* 同时异步委托还可以将异常封送回调用方。
*/
//static void main()
//{
// ThreadPool.QueueUserWorkItem(Go);
// ThreadPool.QueueUserWorkItem(Go, 123);
// Console.ReadKey();
//}
//static void Go(object data)
//{
// Console.WriteLine("hello form the thread pool!" + data);
//}
/*
要使用非泛型的Task类,调用Task.Factory.StartNew,并传递目标方法的委托:
*/
//static void Main()
//{
// Task.Factory.StartNew(Go);
// Console.ReadKey();
//}
//static void Go()
//{
// Console.WriteLine("Hello from thread pool!");
//}
//static void Main()
//{
// Func<string, int> method = Work;
// IAsyncResult cookie = method.BeginInvoke("test", null, null);
//
// 这里可以并行执行其它任务
//
//int result = method.EndInvoke(cookie);
//Console.WriteLine("String length is: " + result);
//Console.ReadKey();
//}
//static int Work(string s) { return s.Length; }
/*
下一步是同步(synchronization):为期望的结果协调线程的行为。当多个线程访问同一个数据时,同步尤其重要,但是这是一件非常容易搞砸的事情。
同步构造可以分为以下四类:
简单的阻塞方法
这些方法会使当前线程等待另一个线程结束或是自己等待一段时间。Sleep、Join与Task.Wait都是简单的阻塞方法。
锁构造
锁构造能够限制每次可以执行某些动作或是执行某段代码的线程数量。排它锁构造是最常见的,它每次只允许一个线程执行,从而可以使得参与竞争的线程在访问公共数据时不会彼此干扰。标准的排它锁构造是lock(Monitor.Enter/Monitor.Exit)、Mutex与 SpinLock。非排它锁构造是Semaphore、SemaphoreSlim以及读写锁。
信号构造
信号构造可以使一个线程暂停,直到接收到另一个线程的通知,避免了低效的轮询 。有两种经常使用的信号设施:事件等待句柄(event wait handle )和Monitor类的Wait / Pluse方法。Framework 4.0 加入了CountdownEvent与Barrier类。
非阻塞同步构造
非阻塞同步构造通过调用处理器指令来保护对公共字段的访问。CLR 与 C# 提供了下列非阻塞构造:Thread.MemoryBarrier 、Thread.VolatileRead、Thread.VolatileWrite、volatile关键字以及Interlocked类。
*/
}
//public delegate void ThreadStart();
}
C#多线程学习笔记的更多相关文章
- java多线程学习笔记——详细
一.线程类 1.新建状态(New):新创建了一个线程对象. 2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中, ...
- JAVA多线程学习笔记(1)
JAVA多线程学习笔记(1) 由于笔者使用markdown格式书写,后续copy到blog可能存在格式不美观的问题,本文的.mk文件已经上传到个人的github,会进行同步更新.github传送门 一 ...
- 多线程学习笔记九之ThreadLocal
目录 多线程学习笔记九之ThreadLocal 简介 类结构 源码分析 ThreadLocalMap set(T value) get() remove() 为什么ThreadLocalMap的键是W ...
- java进阶-多线程学习笔记
多线程学习笔记 1.什么是线程 操作系统中 打开一个程序就是一个进程 一个进程可以创建多个线程 现在系统中 系统调度的最小单元是线程 2.多线程有什么用? 发挥多核CPU的优势 如果使用多线程 将计算 ...
- Java多线程学习笔记(一)——多线程实现和安全问题
1. 线程.进程.多线程: 进程是正在执行的程序,线程是进程中的代码执行,多线程就是在一个进程中有多个线程同时执行不同的任务,就像QQ,既可以开视频,又可以同时打字聊天. 2.线程的特点: 1.运行任 ...
- java 多线程学习笔记
这篇文章主要是个人的学习笔记,是以例子来驱动的,加深自己对多线程的理解. 一:实现多线程的两种方法 1.继承Thread class MyThread1 extends Thread{ public ...
- Java多线程学习笔记--生产消费者模式
实际开发中,我们经常会接触到生产消费者模型,如:Android的Looper相应handler处理UI操作,Socket通信的响应过程.数据缓冲区在文件读写应用等.强大的模型框架,鉴于本人水平有限目前 ...
- Java多线程学习笔记
进程:正在执行中的程序,其实是应用程序在内存中运行的那片空间.(只负责空间分配) 线程:进程中的一个执行单元,负责进程汇总的程序的运行,一个进程当中至少要有一个线程. 多线程:一个进程中时可以有多个线 ...
- C# 多线程学习笔记 - 3
本文主要针对 GKarch 相关文章留作笔记,仅在原文基础上记录了自己的理解与摘抄部分片段. 遵循原作者的 CC 3.0 协议. 如果想要了解更加详细的文章信息内容,请访问下列地址进行学习. 原文章地 ...
- C# 多线程学习笔记 - 2
本文主要针对 GKarch 相关文章留作笔记,仅在原文基础上记录了自己的理解与摘抄部分片段. 遵循原作者的 CC 3.0 协议. 如果想要了解更加详细的文章信息内容,请访问下列地址进行学习. 原文章地 ...
随机推荐
- [Spring框架]Spring IOC的原理及详解。
这里感谢 CSDN 的原博客:http://blog.csdn.net/m13666368773/article/details/7802126 看后 受益匪浅,这里再重温一遍Spring IOC ...
- c#设计模式-命令模式
一. 命令(Command)模式 命令(Command)模式属于对象的行为模式[GOF95].命令模式又称为行动(Action)模式或交易(Transaction)模式.命令模式把一个请求或者操作封装 ...
- Chrome清除dns缓存
Chrome清除dns缓存 为了加快访问速度,Google Chrome浏览器采用了预提DNS记录,在本地建立DNS缓存的方法,加快网站的连接速度.你在谷歌Chrome浏览器的地址栏中输入about: ...
- CooMark网页颜色取色表
CooMark网页颜色取色表 艾利斯兰 - #F0F8FF - aliceblue 古董白 - #FAEBD7 - antiquewhite 浅绿色 - #00FFFF - aqua 碧绿色 - #7 ...
- 快速入门系列--CLR--02多线程
最近,由于基础框架的整体升级,因此需要更新所有相关项目的DLL文件.这个过程存在不小的风险,因此也对发布后的生产服务器进行了密切的监控,结果还是出现了个别应用出现异常的情况,很快的占用了大量的服务器内 ...
- 插入排序java代码
/** * 插入排序 * * 原理:从数组中取出一个值插入到一个左边已经排好序的数组片段中 * * @param a * @return */ public long[] InsertSort(lon ...
- Android切换动画之ViewPager
有过开发经验的程序员都知道这个效果,就是当我们第一次安装一个软件时有一个使用说明的图片切换效果,他是如何实现的呢?今天我们就一起学习一下吧,难度系数1.0,就是只要你仔细分析,都可以学会.废话不多说, ...
- javaWeb之maven多数据库环境的配置信息
在使用maven构建的web项目里,不管采用的是什么orm框架,数据库写死了必然不是最灵活的方式.所以通过maven 的buid方式可以动态的分配数据库信息 比如在jdbc.properties中,可 ...
- Quartz应用实践入门案例一(基于Web环境)
Quartz是一个完全由java编写的开源作业调度框架,正是因为这个框架整合了许多额外的功能,所以在使用上就显得相当容易.只是需要简单的配置一下就能轻松的使用任务调度了.在Quartz中,真正执行的j ...
- MyBaits学习
一:配置MyBaits的开发环境 1.1.核心配置文件 正如hibernate一样,MyBaits也有一个核心的配置文件,它包含着数据源地址,用户名,密码等,还有着各个实体类的配置文件,配置文件是xm ...