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