1 线程与进程
进程:进程可以理解为一块包含了某些些资源的内存区域,操作系统通过进程这一方式把他的工作划分为不同的单元。一个应用程序可以对应于多个进程。
线程:线程是进程中的独立执行单元, 对于操作系统而言,他通过调度线程来使应用程序工作。一个进程中至少包含一个线程,该线程称为主线程。
线程和进程之间的关系可以理解为:线程是进程中的执行单元,操作系统通过调度线程来使应用程序工作;而进程则是线程的容器,他由操作系统创建,又在具体的执行过程中创建了线程。
线程是由操作系统负责调度
同时线程具有优先级:一共具有7个不同的优先级别
线程有前后台之分:主线程一直都是前台线程,同时我们可以使用Thread类来创建前台线程。
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace 多线程02
{
class Program
{
static void Main(string[] args)
{
Thread parmThread = new Thread(new ParameterizedThreadStart(Worker));
parmThread.Name = "线程1";
parmThread.Start("123");
Console.WriteLine("从主线程返回");
}
private static void Worker(object data)
{
Thread.Sleep(1000);
Console.WriteLine("传入的参数为:"+data.ToString());
Console.WriteLine("从线程1返回");
Console.Read();
}
}
}
二 线程池
线程池是指用来存放应用程序中要使用的线程集合,你可以理解为一个存放线程的地方,这种集中存放的方式有利于对线程进行管理。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace 线程池01
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("主线程ID={0}", Thread.CurrentThread.ManagedThreadId);
ThreadPool.QueueUserWorkItem(CallBackWorkItem);
ThreadPool.QueueUserWorkItem(CallBackWorkItem, "work");
Thread.Sleep(3000);
Console.WriteLine("主线程退出");
}
private static void CallBackWorkItem(object state)
{
Console.WriteLine("线程池开始执行");
if (state != null)
{
Console.WriteLine("线程池线程ID={0} 传入的参数为{1}", Thread.CurrentThread.ManagedThreadId, state.ToString());
}
else
{
Console.WriteLine("线程池线程ID={0}", Thread.CurrentThread.ManagedThreadId);
}
}
}
}
三 线程同步
线程同步技术存在的意义在于:确保某一时刻只有一个线程再操作共享资源。多线程应用程序可以调高程序的性能,但是当我们创建多个线程后,可能会出现一种情况,即多个线程同时去访问某一个共享资源,这将损坏资源中所保存的数据,因此,我们需要使用到线程同步技术。
使用监视器对象(Monitor)能够确保线程拥有对共享资源的互斥访问权。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace 线程同步01
{
class Program
{
static int tickets = 100;
static object gloalObj = new object();//辅助对象
static void Main(string[] args)
{
Thread thread1 = new Thread(SaleTicketThread1);
Thread thread2 = new Thread(SaleTicketThread2);
thread1.Start();
thread2.Start();
}
private static void SaleTicketThread1()
{
while (true)
{
try
{
Monitor.Enter(gloalObj);//在 object对象上获得排他锁
Thread.Sleep(1);
if (tickets>0)
{
Console.WriteLine("线程1出票:", + tickets--);
}
else
{
break;
}
}
finally
{
Monitor.Exit(gloalObj);//释放排他锁
}
}
}
private static void SaleTicketThread2()
{
while (true)
{
try
{
Monitor.Enter(gloalObj);//在 object对象上获得排他锁
Thread.Sleep(1);
if (tickets > 0)
{
Console.WriteLine("线程2出票:", + tickets--);
}
else
{
break;
}
}
finally
{
Monitor.Exit(gloalObj);//释放排他锁
}
}
}
}
}
四 线程同步存在的问题
在设计应用程序时,应尽量比卖你使用线程同步,它存在一些问题:
1 使用繁琐:使用过程中需要加锁和释放锁,麻烦
2 影响程序性能:加锁和释放锁需要时间,并且决定哪个线程线获取锁的时候,CPU需要进行协调,同样需要时间。
3 回导致线程阻塞:多线程中,线程同步每次只允许一个线程访问资源,导致系统回创建更多的线程,CPU的调度工作会越发的繁重。