一直对多线程都闹不清楚,今天用现成做了几个程序,还是不怎么明朗,这里对线程好好总结一下,还要好好的理解。
多线程有时怎么实现的:在需要处理器时间的线程之间分割可用处理器时间,并轮流为每个线程分配处理器时间片。当前执行的线程在其时间片结束时被挂起,而另一个线程继续运行。当系统从一个线程切换到另一个线程时,它将保存被抢先的线程的线程上下文,并重新加载线程队列中,下一个线程的已保存下城上下文。
时间片的长度取决于操作系统和处理器。由于每个时间片都很小,因此即使只有一个处理器,多个线程看起来也是在同时执行。
线程中的类与方法:
static void Main(string[] args)
{
ThreadStart st = new ThreadStart(F1);//是一个委托 括号里面应该是方法
Thread t1 = new Thread(st);//可以省去委托 直接把方法传进去 方法类型有两种 一种是无参的 一种是有参的参数为Object类型的
ThreadStart st2 = new ThreadStart(F2);
Thread t2 = new Thread(st2);
t1.Start();
t2.Start();
t1.Suspend();//挂起 但是这个方法已过时
t1.Resume();//唤醒挂起的线程 但是这个方法也过时了
}
static void F1()
{
while (true)
{
Console.WriteLine("1111111111");
Thread.Sleep(1000);
}
}
static void F2()
{
while (true)
{
Console.WriteLine("2222222222");
Thread.Sleep(1000);
}
}
这个例子比较的有意思每次运行的结果都不一样 还不是很明白 不怎么理解线程的调用
class Program
{
static Thread t1,t2;
static void Main(string[] args)
{
ThreadStart s1 = new ThreadStart(F1);
t1 = new Thread(s1);
ThreadStart s2 = new ThreadStart(F2);
t2 = new Thread(s2);
t1.Start();
t2.Start();
}
static void F1()
{
for (int i = 0; i < 10; i++)
{
if (i == 5)
{
t2.Join();//调用线程1的时候会阻塞自己 让线程2先执行
}
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine("111111111111");
Thread.Sleep(1000);
}
}
static void F2()
{
for (int i = 0; i < 10; i++)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("2222222222");
Thread.Sleep(1000);
}
}
}
下面用一个买书的小例子来说明线程的lock方法,类似于生产者消费者问题
public class BookShop
{
int num = 1;//共享资源
public void Sale()
{
lock (this)//同步控制
{
if (num > 0)
{ //卖书过程
Thread.Sleep(1000);
num = num - 1;
Console.WriteLine("售出一本");
}
else
{
Console.WriteLine("没有了");
}
}
}
}
Monitor 类通过向单个线程授予对象锁来控制对对象的访问。
对象锁提供限制访问代码块(通常称为临界区)的能力。当一个线程拥有对象的锁时,其他任何线程都不能获取该锁。 :
名称 说明 Enter 在指定对象上获取排他锁。 Exit 释放指定对象上的排他锁。 Pulse 通知等待队列中的线程锁定对象状态的更改。 PulseAll 通知所有的等待线程对象状态的更改。 TryEnter 试图获取指定对象的排他锁。 Wait 例子: void DataHandle() { Monitor.Enter(this); for (int i = 0; i <=20; i++) { if (dataOutput == 5) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Handle睡了"); Console.ForegroundColor = ConsoleColor.Black; Monitor.Wait(this); } dataOutput++; Console.WriteLine(Thread.CurrentThread.Name + " 正在处理第" + dataOutput + "笔数据;!"); Thread.Sleep(100); if (dataOutput == 5) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Handle让别人醒"); Console.ForegroundColor = ConsoleColor.Black; Monitor.PulseAll(this); Console.WriteLine(); } } }
void DataPrint() { Monitor.Enter(this); do { if (dataOutput == 0) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Print睡了"); Console.ForegroundColor = ConsoleColor.Black; Monitor.Wait(this); } Console.Write(Thread.CurrentThread.Name + " 正在打印第" + dataOutput + "笔数据;!"); Thread.Sleep(100); dataOutput--; dataSum++; Console.WriteLine(“总打印数据笔数" + dataSum); if (dataOutput == 0) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Print让别人醒"); Console.ForegroundColor = ConsoleColor.Black; Monitor.PulseAll(this); Console.WriteLine(); } } while (dataSum < 20); Monitor.Exit(this); } 释放对象上的锁并阻止当前线程,直到它重新获取该锁。
调用
static void Main(string[] args)
{
Program pro = new Program();
pro.StartThread();
}
int dataSum = 0;
int dataOutput = 0;
void StartThread()
{
Thread th1 = new Thread(DataHandle);
th1.Name = "数据处理";
Thread th2 = new Thread(DataPrint);
th2.Name = "数据打印";
th1.Start();
th2.Start();
}
线程并发执行的时候是有优先级的,线程优先级是枚举类型。元素分别为:
优先级从高到低分别为Highest ,AboveNorma l,Norma l, BelowNormal. Lowest
下面用以个Winform下的赛马小程序来说明线程的优先调用:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;
}
private void label1_Click(object sender, EventArgs e)
{
}
Thread th1;
Thread th2;
Thread th3;
private void button1_Click(object sender, EventArgs e)
{
th1 = new Thread(Run);
th1.Priority = ThreadPriority.Lowest;
th2 = new Thread(Run);
th2.Priority = ThreadPriority.Normal;
th3 = new Thread(Run);
th3.Priority = ThreadPriority.Highest;
th3.Name = "aaa";
th1.Start(pictureBox1);
th2.Start(pictureBox2);
th3.Start(pictureBox3);
}
void Run(object o)
{
int i = 0;
PictureBox pb = o as PictureBox;
bool mark = true;
while (true)
{
i++;
if (i == 1000)
{
if ( Thread .CurrentThread.Name=="aaa")
Thread.Sleep(1500);
}
if (mark && pb.Left < 791)
{
pb.Left++;
Thread.Sleep(10);
}
else
{
mark = false;
if (!mark && pb.Left > 0)
{
pb.Left--;
Thread.Sleep(10);
}
else
{
mark = true;
}
}
}
}
}
}