关于线程学习过程的笔记

由于最近在开发公司的客户端,在上传下载过程中需要用到多线程然后就仔细的了解了一下,借鉴了网上的一些实例看了一下总结一下。

首先要了解三个定义:

程序(Program):

计算机指令的集合,它以文件的形式存储在磁盘上。

进程(Process):

一个程序在其自身的地址空间中的一次执行活动。

资源申请、调度和独立运行的单位,因此,它使用系统中的运行资源;而程序不能申请系统资源,不能被系统调度,也不能作为独立运行的单位,因此,它不占用系统的运行资源。

线程(Thread):

是进程中的一个单一的连续控制流程。一个进程可以拥有多个线程。

线程又称为轻量级进程,它和进程一样拥有独立的执行控制,由操作系统负责调度,区别在于线程没有独立的存储空间,而是和所属进程中的其他线程共享一个存储空间,这使得线程间的通信远较进程简单

 

 

看了以前某个带我的老师发布的一个ppt 对于多线程主要说了这么一句话:

多线程代码难在如何以正确的方式处理3点:

1.保持线程的"原子性"

2.避免死锁

3.避免造成执行时的不确定性

这三点很容易理解。所以在多线程编程的时候就把这三点当做编程时候的原则来写代码,然后来讨论一下多线程编写的时候我遇到的问题吧。

1、线程1中有一个指令A,线程2中有一个指令B,A既可能先于B执行,也可能晚于B执行,这个顺序不确定。(更具欺骗性的是:一段代码可能大多数时候能一致的执行,但偶尔会出现错乱,这正是多线程编程的关键问题。)

 这个问题我遇到过,因为我以前没有做过多线程的程序,然后写着运行起来发现有些代码执行顺序偶尔会出现不对。

然后 主要看了网上的关于多线程的一些实例,线程主要就是几个方法和属性:

 

Start()

导致操作系统将当前实例的状态更改为 
ThreadState.Running

Abort()

在调用此方法的线程上引发 ThreadAbortException,以开始终止此线程的过程。 调用此方法通常会终止线程。

Join()

在继续执行标准的 COM 和 SendMessage 消息泵处理期间,阻塞调用线程,直到某个线程终止为止。

Priority

获取或设置一个值,该值指示线程的调度优先级

ThreadState

获取一个值,该值包含当前线程的状态。

Suspend

已过时。挂起线程,或者如果线程已挂起,则不起作用。

Resume

已过时。继续已挂起的线程。

Interrupt

中断处于 WaitSleepJoin状态的县城

 然后在网上找了几个例子有些自己 稍微修改了一下   可以参考下

 第一个首先银行存钱取钱的时候 用卡 和 存折 多线程操作

public class BrankAccount
    {
        double money = 20023040.2300;
        //volatile将禁止将num优化到各个线程的存储区中
        volatile int num = 50;
        object obj = new object();
        /// <summary>
        /// 取钱
        /// </summary>
        public void GetMoney()
        {
            for (int i = 50; i > 0; i--)
            {
                lock (obj)
                {
                    if (num > 0)
                    {
                        int j = (new Random()).Next(100, 5000) + i;
                        var str = string.Format(" 用{0}取走{1}  {2}元", Thread.CurrentThread.Name, num, j * DateTime.Now.Second * 479);
                        Console.WriteLine(str);
                        num--;
                    }
                }
            }
        }

         
    }

然后另一个就是死锁的例子

 object locker2 = new object();

        public void MainThread()
        {
            new Thread(() =>
            {
                lock (this)   //获取锁locker1
                {
                    Thread.Sleep(1000);
                    lock (locker2) //尝试获取locker2
                    {
                        Console.WriteLine("this,locker2");
                    }
                }
            }).Start();

            lock (locker2) //获取锁locker2
            {
                Thread.Sleep(1000);
                lock (this) //尝试获取locker1
                {
                    Console.WriteLine("locker2,this");
                }
            }
        }

还有一个是关于Join的实例

   public class Mother
    {
        public void CookDinner()
        {
            Console.WriteLine();
            Console.WriteLine("妈妈准备做饭");
            Console.WriteLine("妈妈发现没有米");
            Console.WriteLine("妈妈叫儿子去买");
            Thread tr = new Thread(new Son().BuyRice);
            tr.IsBackground = true;
            tr.Start();
            tr.Join();
            Console.WriteLine("妈妈等待儿子回来");
            Console.WriteLine("妈妈开始煮饭");
            Console.WriteLine("妈妈把饭煮好了");
        }
    }

    public class Son
    {
        public void BuyRice()
        {
            Console.WriteLine("儿子出去买米~");
            Console.WriteLine("儿子买米要5分钟~");
            for (int i = 0; i <= 5; i++)
            {
                Thread.Sleep(1000);
                Console.WriteLine(i + "分钟过去了...");
            }
            Console.WriteLine("儿子买米回家了~!");
        }
    }
可以尝试把tr.Join()去掉 那么就会成为 “妈妈已经把饭做好了,然后再等待儿子5分钟的买米”

首先说明我也还是个初学者,有些东西是别人写的,我只是学习,分享哈,有不对的希望高手详解一下。谢谢。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。