一直对多线程都闹不清楚,今天用现成做了几个程序,还是不怎么明朗,这里对线程好好总结一下,还要好好的理解。

 多线程有时怎么实现的:在需要处理器时间的线程之间分割可用处理器时间,并轮流为每个线程分配处理器时间片。当前执行的线程在其时间片结束时被挂起,而另一个线程继续运行。当系统从一个线程切换到另一个线程时,它将保存被抢先的线程的线程上下文,并重新加载线程队列中,下一个线程的已保存下城上下文。

时间片的长度取决于操作系统和处理器。由于每个时间片都很小,因此即使只有一个处理器,多个线程看起来也是在同时执行。

线程中的类与方法:

  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;
                    }
                }
            }
        }
    }
}