C#中的线程,任务和同步

Thread类,线程:

public static void XianChengTest() //定义一个方法
        {
            Console.WriteLine("启动线程");
            Thread.Sleep(5000);
            Console.WriteLine("结束线程");
        }

Thread thread = new Thread(XianCheng.XianChengTest); //把方法放到线程里面

thread.Start();  //启动线程,相当于启动方法。

线程只能传递拥有一个参数的方法,如果想传递多个数据可以传递类或者结构体的方式进行传递。

public static void ChuanDiCanshu(Data data)  //定义一个传递数据的方法
        {
            Console.WriteLine("这个人叫"+data.name+"他今年"+data.age+"岁了");
        }

声明一个结构体,对数据进行规范

public struct Data
    {
        public int age;
        public string name;
    }

把方法放入到一个新的线程对象中,通过Start方法启动该线程实现数据的传递。

Data data = new Data();
data.age = 1;
data.name = "张三";
Thread thread1 = new Thread(() => { XianCheng.ChuanDiCanshu(data);}) ;
thread1.Start();

根据自定义类传递线程数据

 public class ChuanDiLei   //自定义类
    {
        private int age;

        public int Age { get => age; set => age = value; }

        private string name;
        public string Name
        {
            get { return name; }
            set { Name = value; }
        }

        public ChuanDiLei(int age,string name)
        {
            this.age = age;
            this.name = name;
        }

        public void GenJvLeiChuanDiData()
        {
            Console.WriteLine("这个人叫" + name + "他今年" + age + "岁了");
        }
    }

ChuanDiLei chuanDiLei=new ChuanDiLei(30,"王五");    // 创建对象,构造函数赋值
Thread thread2 = new Thread(chuanDiLei.GenJvLeiChuanDiData); //把对象中的方法传递给线程,因为在构造该对象的时候就给里面的字段赋值了,所以该方法能够访问到对象字段里面的内容,把对象的方法放到线程中,最后启动线程,实现方法的启用
thread2.Start();

线程分为前台线程和后台线程,当所有的前台线程执行完后,程序会结束运行,在创建线程对象的时候可以设置是否为前台线程。

Thread thread2 = new Thread(chuanDiLei.GenJvLeiChuanDiData) { IsBackground=true};

PS:线程池中的线程全部都是后台线程。

线程的优先级一共有五个等级,分别是最高级,高级,普通,低级,最低级,是线程对象的属性,在创建线程对象的时候可以进行修改

Thread thread2 = new Thread(chuanDiLei.GenJvLeiChuanDiData) { Priority=ThreadPriority.Highest};

任务:

任务是一种特殊的线程,其方法和线程差不多,任务的本质是使用系统的内置线程池,所以任务中的线程都是后台线程

Task task = new Task(()=> { XianCheng.ChuanDiCanshu(data);});
task.Start();

线程的资源冲突问题:

在使用多个线程对一个对象中的同一个方法进行多次运行时,可能会造成资源的冲突问题。

public class ZiYuanChongTu
    {
        private int state = 5;
        public void ChangeState()
        {
            if (state == 5)
            {
                state++;
                Console.WriteLine(state);
            }
            state = 5;
        }
    }

比如上述类中的字段state在创建对象后存储在多个线程中,线程中的state指向的地址都是一个,有的线程刚刚执行到state++的地方,有的可能执行到了state=5的地方,因此会导致state的值不统一,造成资源上的冲突,针对这一情况就使用锁的思想,当一个线程已经取得该方法后,将这个方法锁起来不然其他的线程用,等用完了再解开,以此让其他的线程使用。

public class ZiYuanChongTu
    {
        private Object _lock=new Object();
        private int state = 5;
        public void ChangeState()
        {
            lock (_lock)
            {
                if (state == 5)
                {
                    state++;
                    Console.WriteLine(state);
                }
                state = 5;
            }
        }
    }

线程中的死锁问题,死锁问题是当出现了两把锁或者多把锁的时候,我们有两个方法一个是先拿第一把锁然后再拿第二把锁,另一个是先拿第二把锁再拿第一把锁,当这两个方法同时执行的时候,第一把锁被方法1持有,第二把锁被方法2持有,最后导致程序无法继续执行下去。解决办法:规定所有的方法持锁的顺序必须得是一样的。

问题:

public class ZiYuanChongTu
    {
        private Object _lock=new Object();
        private Object _lock1 = new Object();
        private int state = 5;
        public void ChangeState()
        {
            lock (_lock1)
            {
                lock ( _lock)
                {
                    if (state == 5)
                    {
                        state++;
                        Console.WriteLine(state);
                    }
                    state = 5;
                } 
            }
        }
        public void ChangeState1()
        {
            lock (_lock1)
            {
                lock (_lock)
                {
                    if (state == 5)
                    {
                        state++;
                        Console.WriteLine(state);
                    }
                    state = 5;
                }
            }
        }
    }

解决:

public class ZiYuanChongTu
    {
        private Object _lock=new Object();
        private Object _lock1 = new Object();
        private int state = 5;
        public void ChangeState()
        {
            lock (_lock1)
            {
                lock ( _lock)
                {
                    if (state == 5)
                    {
                        state++;
                        Console.WriteLine(state);
                    }
                    state = 5;
                } 
            }
        }
        public void ChangeState1()
        {
            lock (_lock1)
            {
                lock (_lock)
                {
                    if (state == 5)
                    {
                        state++;
                        Console.WriteLine(state);
                    }
                    state = 5;
                }
            }
        }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值