新建(new 对象)
就绪(等待CPU调度)
运行(CPU正在运行)
阻塞(等待阻塞、同步阻塞等)
死亡(对象释放)
进程中第一个被执行得线程称为主线程,程序开始时,主线程自动创建。
属性 | 描述 |
---|---|
CurrentContext | 获取线程正在执行的当前上下文 |
CurrentCulture | 获取或设置当前线程的区域性 |
CurrentPrinciple | 获取或设置当前线程的负责人 |
CurrentThread | 获取当前正在运行的线程 |
CurrentUICulture | 获取或设置资源管理器使用的当前区域性以便在运行时查找区域性特定的资源获取或设置资源管理器使用的当前区域性以便在运行时查找区域性特定的资源 |
ExecutionContext | 获取一个 ExecutionContext 对象,该对象包含有关当前线程的各种上下文的信息 |
IsAlive | 获取一个值,该值指示当前线程的执行状态 |
IsBackground | 获取或设置一个值,该值指示某个线程是否为后台线程 |
IsThreadPoolThread | 获取一个值,该值指示线程是否属于托管线程池 |
ManagedThreadId | 获取当前托管线程的唯一标识符 |
Name | 获取或设置线程的名称 |
Priority | 获取或设置一个值,该值指示线程的调度优先级 |
ThreadState | 获取一个值,该值包含当前线程的状态 |
Thread.CurrentThread.Priority: 线程优先级,设置为高优先级的线程并不会一定在低优先级的线程之前执行,只是增加了优先执行的概率。
public static void Test()
{
Thread thread = Thread.CurrentThread;//获取当前执行得线程对象
thread.Name = "MainThread";
Console.WriteLine("this is {0},ID={1},优先级:{2}", thread.Name, Thread.CurrentThread.ManagedThreadId
,Thread.CurrentThread.Priority);
}
创建线程方法:
Thread thread = new Thread(new ThreadStart(CreadThread));
Thread thread=new Thread(new ParameterizedThreadStart(CreadThread!));
一般方法参数只能为object
public class ThreadCreadMethod
{
public static void CreadMethod01()
{
//不带参数的方法创建线程
Thread thread = new Thread(new ThreadStart(CreadThread));
thread.Name = "生出小兵逻辑";
thread.Start();
}
///带参数的线程
public static void CreadMethod02()
{
Thread thread=new Thread(new ParameterizedThreadStart(CreadThread!));
thread.Name = "生出野怪";
thread.Start(thread.Name);
}
public static void CreadThread()
{
for (int i = 0; i < 50; i++)
{
Console.WriteLine(Thread.CurrentThread.Name+":"+i);
}
}
///
/// 带参数
///
public static void CreadThread(object para)
{
Thread.CurrentThread.Name = para.ToString();
for (int i = 0; i < 50; i++)
{
Console.WriteLine(Thread.CurrentThread.Name + ":" + i);
}
}
}
public void Test()
{
ThreadCreadMethod.CreadMethod01();
ThreadCreadMethod.CreadMethod02();
}
///
/// 直接通过task创建线程
///
public static void CreadMethod01()
{
var task = new Task(() =>
{
Console.WriteLine("代码模块 或 调用方法");
CreateTask();
});
task.Start();
}
///
/// 通过factory创建线程
///
public static void CreadMethod02()
{
Task.Factory.StartNew(() =>
{
Console.WriteLine("通过factory创建线程 ====代码模块 或 调用方法");
CreateTask();
});
}
///
/// 通过Task.run创建线程 比较常用[这种方式会放到线程池,重用线程]
///
public static void CreadMethod03()
{
Task.Run(() =>
{
Console.WriteLine("通过Task.run创建线程 ====代码模块 或 调用方法");
CreateTask();
});
}
public static void CreateTask()
{
Thread.CurrentThread.Name = "Task线程一";
for (int i = 0; i < 20; i++)
{
Console.WriteLine(Thread.CurrentThread.Name + ":" + i);
}
}
}
默认情况下,创建的线程是前台线程。只要前台线程中的任何一个正在运行,它就可以使应用程序保持活动状态,而后台线程则不会。一旦所有前台线程完成,应用程序结束,所有仍在运行的后台线程终止。
设置IsBackground为true,即为后台线程。
public class BackGroundClassTest
{
public static void TestBackGround()
{
///演示前台线程
BackGroundTest backGroundTest = new BackGroundTest(10);
///创建前台线程
Thread fthread = new Thread(new ThreadStart(backGroundTest.RunLoop));
fthread.Name = "前台线程";
///演示后台线程
BackGroundTest backGroundTest1 = new BackGroundTest(20);
///创建前台线程
Thread bthread1 = new Thread(new ThreadStart(backGroundTest1.RunLoop));
bthread1.Name = "后台线程";
bthread1.IsBackground= true;
fthread.Start();
bthread1.Start();
}
}
class BackGroundTest
{
private int Count;
public BackGroundTest(int count)
{
this.Count = count;
}
public void RunLoop()
{
string threadname = Thread.CurrentThread.Name;
for (int i = 0; i < Count; i++)
{
Console.WriteLine($"{threadname}计数:{i}");
Thread.Sleep( 10 );
}
Console.WriteLine($"{threadname}完成计数");
}
}
Console.WriteLine("主线程开始");
BackGroundClassTest.TestBackGround();
Console.WriteLine("主线程结束");
当 bthread1.IsBackground= true时,即为后台线程时。运行结果为:
当 bthread1.IsBackground= false时,即为前台线程时。运行结果为:
举个例子:访问资源失败时,需要等待一段时间继续访问,这个时候可以调用sleep方法
public class SleepClass1
{
public static void Test()
{
Console.WriteLine("Enter Main");
Thread thread1 = new Thread(new ThreadStart(Counter));
Thread thread2 = new Thread(new ThreadStart(Counter2));
thread2.Priority= ThreadPriority.Highest;
thread1.Start();
thread2.Start();
Console.WriteLine("EXIT Main");
}
public static void Counter()
{
Console.WriteLine("Enter Counter1");
for (int i = 0; i < 50; i++)
{
Console.Write(i + " ");
if (i==10)
{
Console.WriteLine();
Thread.Sleep(1000);
}
}
Console.WriteLine("Exit Counter1");
}
public static void Counter2()
{
Console.WriteLine("Enter Counter2");
for (int i = 51; i < 100; i++)
{
Console.Write(i + " ");
if (i ==70)
{
Console.WriteLine();
Thread.Sleep(1000);
}
}
Console.WriteLine("Exit Counter2");
}
}
使用线程的Interrupt方法只可以中断处于 WaitSleepJoin 状态的线程,当线程状态不再为 WaitSleepJoin时,线程将恢复执行。
public class InterruptClass1
{
static Thread Threadsleep;
static Thread Threadwork;
public static void test()
{
Threadsleep = new Thread(new ThreadStart(SleepingThread));
Threadwork = new Thread(new ThreadStart(AwakeThread));
Threadsleep.Start();
Threadwork.Start();
}
public static void SleepingThread()
{
for (int i = 0; i < 50; i++)
{
Console.Write(i + " ");
if (i == 10 || i == 20 || i == 30)
{
Console.Write("sleeping-----" + i);
try
{
Thread.Sleep(20);
}
catch (ThreadInterruptedException er)
{
Console.WriteLine(er.Message);
}
}
}
}
///
/// 线程状态为ThreadState.WaitSleepJoin时,才能调用Interrupt方法
///
public static void AwakeThread()
{
for (int i = 51; i < 100; i++)
{
Console.Write(i + " ");
if (Threadsleep.ThreadState==ThreadState.WaitSleepJoin)
{
Console.WriteLine(" Threadsleep is Interrupt");
Threadsleep.Interrupt();
}
}
}
}
Join方法主要用来阻塞调用线程,直到某个线程终止或经过了指定时间为止,使得线程变得有序起来
public class JoinClass
{
public static void Test()
{
Thread thread = new Thread(ThreadMethod!);
thread.Name = "线程A";
Thread thread0 = new Thread(ThreadMethod!);
thread0.Name = "线程B";
thread.Start();
thread.Join();
thread0.Start();
thread0.Join();
for (int i = 0; i <= 3; i++)
{
Console.WriteLine($"我是主线程,循环了{i}次");
}
}
public static void ThreadMethod(object parameter)
{
for (int i = 0; i <= 3; i++)
{
Console.WriteLine($"我是{Thread.CurrentThread.Name}循环了{i}次");
Thread.Sleep(300);
}
}
}
多个线程使用同一资源,会出现数据竞争问题,因而需要线程同步来解决这一问题:locker、最大粒度、Monitor
public class ThreadSync
{
public static int Counter = 0;
///
/// 线程未同步---存在数据竞争问题
///
public static void TestNoSyncThread()
{
Thread thread1 = new Thread(() =>
{
for (int i = 0; i < 1000; i++)
{
Counter++;
Thread.Sleep(1);
}
});
thread1.Start();
Thread thread2 = new Thread(() =>
{
for (int i = 0; i < 1000; i++)
{
Counter++;
Thread.Sleep(1);
}
});
thread2.Start();
Thread.Sleep(30000);
Console.WriteLine("线程未同步:"+Counter);
}
}
使用locker同步
public class ThreadSync
{
public static int Counter_locker = 0;
///
/// 线程使用locker同步
///
public static void TestSyncThread_locker()
{
Thread thread1 = new Thread(() =>
{
for (int i = 0; i < 1000; i++)
{
//同步块
lock (locker)
{
Counter_locker++;
}
Thread.Sleep(1);
}
});
thread1.Start();
Thread thread2 = new Thread(() =>
{
for (int i = 0; i < 1000; i++)
{
//同步块
lock (locker)
{
Counter_locker++;
}
Thread.Sleep(1);
}
});
thread2.Start();
Thread.Sleep(30000);
Console.WriteLine("线程使用locker同步:" + Counter_locker);
}
}
[MethodImpl(MethodImplOptions.Synchronized)]
public class ThreadSync
{
static int money = 1000;
///
/// 线程同步使用最大粒度
///
public static void TestSyncThread_Imp()
{
Thread thread1 = new Thread(() =>
{
for (int i = 0; i < 200; i++)
{
同步块
//lock (locker)
//{
// FetchMoney("thread1");
//}
FetchMoney("thread1");
Thread.Sleep(1);
}
});
thread1.Start();
Thread thread2 = new Thread(() =>
{
for (int i = 0; i < 200; i++)
{
同步块
//lock (locker)
//{
// FetchMoney("thread2");
//}
FetchMoney("thread2");
Thread.Sleep(1);
}
});
thread2.Start();
Thread.Sleep(30000);
Console.WriteLine("线程使用最大粒度同步:" + Counter_locker);
}
///
/// 使用最大粒度同步线程
///
///
[MethodImpl(MethodImplOptions.Synchronized)]
public static void FetchMoney(string name)
{
Console.WriteLine("当前余额" + money);
int yu = money - 1;
Console.WriteLine(name+"取钱");
money = yu;
Console.WriteLine(name+"取完了,剩余"+money);
}
}
public class ThreadSync
{
static int money = 1000;
///
/// 必须为静态、object类型
///
public static object locker=new object();
///
/// 使用mointor同步线程
///
///
public static void FetchMoney_mointor(string name)
{
//等待没有人锁定locker对象,就锁定它,然后继续执行
Monitor.Enter(locker);
try
{
Console.WriteLine("当前余额" + money);
int yu = money - 1;
Console.WriteLine(name + "取钱");
money = yu;
Console.WriteLine(name + "取完了,剩余" + money);
}
finally
{
Monitor.Exit(locker);
}
}
public static void TestSyncThread_Imp()
{
Thread thread1 = new Thread(() =>
{
for (int i = 0; i < 200; i++)
{
FetchMoney_mointor("thread1");
Thread.Sleep(1);
}
});
Thread thread2 = new Thread(() =>
{
for (int i = 0; i < 200; i++)
{
FetchMoney_mointor("thread2");
Thread.Sleep(1);
}
});
thread2.Start();
thread1.Start();
thread1.Join();
thread2.Join();
Console.WriteLine("线程使用Monitor同步:" + money);
}
}