笔记
初始小例子
class Program
{
static void Main(string[] args)
{
Console.OutputEncoding = Encoding.Unicode;
//1 基本
Thread.CurrentThread.Name = "主线程";
Thread objt = new Thread(new ThreadStart(Method1));
objt.Name = "子线程";
objt.Start();
Method2();
Console.ReadKey();
}
static void Method1()
{
for (int i = 0; i < 10; i++)
{
Thread.Sleep(100);
Console.WriteLine(i + " Method1:"+Thread.CurrentThread.Name);
}
}
static void Method2()
{
for (int i = 0; i < 10; i++)
{
Thread.Sleep(100);
Console.WriteLine(i + " Method2:" + Thread.CurrentThread.Name);
}
}
}
线程状态
1.unstart 未开始
2.running 调用start后
3.waitsleepjoin 调用wait sleep join 来暂停线程
4.suspendrequested 请求挂起
5.suspended 处于挂起
6.abortrequested 请求终止
7.aborted 终止状态
8.stopped 停止状态
//当计数器达到0,4、8 时,第一个线程进入休眠状态,第二个线程一旦检查到第一个线程处于休眠状态,就
//立即中断第一个线程,使其回到队列中
static Thread sleep;
static Thread awake;
static void SleepThread()
{
for(int i=0;i<10;i++)
{
if(i%4==0)
{
Console.WriteLine("sleepThread sleep at "+i);
try
{
Thread.Sleep(30000);
}
catch (ThreadInterruptedException e)
{
Console.WriteLine("sleepThread 被 唤醒" );
}
}
}
}
static void AwakeThread()
{
for(char i= 'a';i<'z';i++)
{
if (sleep.ThreadState == ThreadState.WaitSleepJoin)
{
Console.WriteLine("awart at "+i);
sleep.Interrupt();
Thread.Sleep(2500);
}
}
}
sleep = new Thread(new ThreadStart(SleepThread));
awake = new Thread(new ThreadStart(AwakeThread));
sleep.Start();
awake.Start();
调用Abort方法的话,那么 会触发指定异常,同时,线程终止
线程同步
//多线程同步,即 在任一时刻,只允许一个线程访问资源
//线程安全 是指 多个线程并发使用某个对象时,该对象总是保持有效状态,常表现为 征用条件和死锁
对上下文同步
[Synchronization]
class CountClass:ContextBoundObject//同步上下文,但是不同步静态内容
通过monitor获取锁
Monitor.Enter(this); //
for(int i=0;i<10;i++)
{
Console.WriteLine("Count = " + count +" ThreadID = "+Thread.CurrentThread.Name);
//Thread.Sleep(100);
}
Monitor.Exit(this);
//首先Monitor.Enter() 获取一个锁, 然后Monitor.Exit() 释放一个锁
//其他线程要等到该锁被释放后才能使用该代码区
Count2 c = new Count2();
Count2 c2 = new Count2();
Count2 c3 = new Count2();
Thread t1 = new Thread(new ParameterizedThreadStart(c.read));
Thread t2 = new Thread(new ParameterizedThreadStart(c.read));
Thread t3 = new Thread(new ParameterizedThreadStart(c2.read));
Thread t4 = new Thread(new ParameterizedThreadStart(c2.read));
t1.Name = "t1";
t2.Name = "t2";
t3.Name = "t3";
t4.Name = "t4";
t1.Start(c3);
t2.Start(c3);
t3.Start(c3);
t4.Start(c3);
class Count2
{
int i = 100;
public void read(Object obj)
{
Console.WriteLine(Thread.CurrentThread.Name + " 进入方法 ");
Monitor.Enter(obj);
for(int j=0;j<20;j++)
{
Console.WriteLine(Thread.CurrentThread.Name + " " + i);
Thread.Sleep(50);
}
Monitor.Exit(obj);
}
}
通过LOCK关键字
lock(this)
{
}
class Count3
{
int i = 100;
public void read(Object obj)
{
Console.WriteLine(Thread.CurrentThread.Name + " 进入方法 ");
lock(obj)
{
for (int j = 0; j < 20; j++)
{
Console.WriteLine(Thread.CurrentThread.Name + " " + i);
Thread.Sleep(50);
}
}
}
}
需要注意,上面的this对象 是需要同步的对象
除了上面三个,还有手工同步类
线程池
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Contexts;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ThreadLLL
{
class Program
{
static void Main(string[] args)
{
Console.OutputEncoding = Encoding.Unicode;
//1 基本
//Thread.CurrentThread.Name = "主线程";
//Thread objt = new Thread(new ThreadStart(Method1));
//Console.WriteLine("当前状态:"+objt.ThreadState);
//objt.Name = "子线程";
//objt.Start();
//Method2();
//当计数器达到0,4、8 时,第一个线程进入休眠状态,第二个线程一旦检查到第一个线程处于休眠状态,就
//立即中断第一个线程,使其回到队列中
//sleep = new Thread(new ThreadStart(SleepThread));
//awake = new Thread(new ThreadStart(AbortThread));
//sleep.Start();
//awake.Start();
//多线程同步,即 在任一时刻,只允许一个线程访问资源
//线程安全 是指 多个线程并发使用某个对象时,该对象总是保持有效状态,常表现为 征用条件和死锁
//用两个线程对countclass类的字段count进行访问,一个读,一个写
//CountClass count = new CountClass();
//Thread read = new Thread(new ThreadStart(count.readCount));
//read.Name = "read";
//Thread write = new Thread(new ThreadStart(count.writeCount));
//write.Name = "write";
//read.Start();
//write.Start();
//同步代码区 使用 Monitor类 和 Lock关键字
//首先Monitor.Enter() 获取一个锁, 然后Monitor.Exit() 释放一个锁
//其他线程要等到该锁被释放后才能使用该代码区
//Count2 c = new Count2();
//Count2 c2 = new Count2();
//Count2 c3 = new Count2();
//Thread t1 = new Thread(new ParameterizedThreadStart(c.read));
//Thread t2 = new Thread(new ParameterizedThreadStart(c.read));
//Thread t3 = new Thread(new ParameterizedThreadStart(c2.read));
//Thread t4 = new Thread(new ParameterizedThreadStart(c2.read));
//t1.Name = "t1";
//t2.Name = "t2";
//t3.Name = "t3";
//t4.Name = "t4";
//t1.Start(c3);
//t2.Start(c3);
//t3.Start(c3);
//t4.Start(c3);
//Lock 锁测试
//Count3 c = new Count3();
//Count3 c2 = new Count3();
//Count3 c3 = new Count3();
//Thread t1 = new Thread(new ParameterizedThreadStart(c.read));
//Thread t2 = new Thread(new ParameterizedThreadStart(c.read));
//Thread t3 = new Thread(new ParameterizedThreadStart(c2.read));
//Thread t4 = new Thread(new ParameterizedThreadStart(c2.read));
//t1.Name = "t1";
//t2.Name = "t2";
//t3.Name = "t3";
//t4.Name = "t4";
//t1.Start(c3);
//t2.Start(c3);
//t3.Start(c3);
//t4.Start(c3);
//手动同步类 interlocked 简单的 加 减 修改 替换
//mutex 与monitoer类似
//ReaderWriterLock 读写锁 多个读,单个写
Count4 c4 = new Count4();
Thread read1 = new Thread(new ThreadStart(c4.read));
read1.Name = "read";
Thread write1 = new Thread(new ThreadStart(c4.write));
write1.Name = "write1";
Thread read2 = new Thread(new ThreadStart(c4.read));
read2.Name = "read2";
Thread write2 = new Thread(new ThreadStart(c4.write));
write2.Name = "write2";
Thread read3 = new Thread(new ThreadStart(c4.read));
read3.Name = "read3";
Thread write3 = new Thread(new ThreadStart(c4.write));
write3.Name = "write3";
write2.Start();
write1.Start();
read2.Start();
read3.Start();
write3.Start();
read1.Start();
Console.ReadKey();
}
static Thread sleep;
static Thread awake;
static void Method1()
{
for (int i = 0; i < 10; i++)
{
Thread.Sleep(1000);
Console.WriteLine("当前状态:" + Thread.CurrentThread.ThreadState);
Console.WriteLine(i + " Method1:" + Thread.CurrentThread.Name);
}
}
static void Method2()
{
for (int i = 0; i < 10; i++)
{
Thread.Sleep(100);
Console.WriteLine(i + " Method2:" + Thread.CurrentThread.Name);
}
}
static void SleepThread()
{
for (int i = 0; i < 10; i++)
{
if (i % 4 == 0)
{
Console.WriteLine("sleepThread sleep at " + i);
try
{
Thread.Sleep(30000);
}
catch (ThreadInterruptedException e)
{
Console.WriteLine("sleepThread 被 唤醒");
}
catch (ThreadAbortException e)
{
Console.WriteLine("终止sleep线程");
}
}
}
}
static void AwakeThread()
{
for (char i = 'a'; i < 'z'; i++)
{
if (sleep.ThreadState == ThreadState.WaitSleepJoin)
{
Console.WriteLine("awart at " + i);
sleep.Interrupt();
Thread.Sleep(2500);
}
}
}
static void AbortThread()
{
for (char i = 'a'; i < 'z'; i++)
{
if (sleep.ThreadState == ThreadState.WaitSleepJoin)
{
Console.WriteLine("Abort at " + i);
sleep.Abort();
Thread.Sleep(2500);
}
}
}
}
[Synchronization]
class CountClass:ContextBoundObject//同步上下文,但是不同步静态内容
{
int count =42;
public void readCount()
{
Monitor.Enter(this); //
for(int i=0;i<10;i++)
{
Console.WriteLine("Count = " + count +" ThreadID = "+Thread.CurrentThread.Name);
//Thread.Sleep(100);
}
Monitor.Exit(this);
}
public void writeCount()
{
Monitor.Enter(this);
for (int i = 0; i < 10; i++)
{
//Thread.Sleep(100);
count++;
Console.WriteLine("Count = " + count + " ThreadID = " + Thread.CurrentThread.Name);
}
Monitor.Exit(this);
}
}
class Count2
{
int i = 100;
public void read(Object obj)
{
Console.WriteLine(Thread.CurrentThread.Name + " 进入方法 ");
Monitor.Enter(obj);
for(int j=0;j<20;j++)
{
Console.WriteLine(Thread.CurrentThread.Name + " " + i);
Thread.Sleep(50);
}
Monitor.Exit(obj);
}
}
class Count3
{
int i = 100;
public void read(Object obj)
{
Console.WriteLine(Thread.CurrentThread.Name + " 进入方法 ");
lock(obj)
{
for (int j = 0; j < 20; j++)
{
Console.WriteLine(Thread.CurrentThread.Name + " " + i);
Thread.Sleep(50);
}
}
}
}
class Count4
{
ReaderWriterLock rw = new ReaderWriterLock();
int i = 100;
public void read()
{
rw.AcquireReaderLock(Timeout.Infinite);
for(int j=0;j<10;j++)
{
Thread.Sleep(20);
Console.WriteLine(Thread.CurrentThread.Name + " read " + i);
}
rw.ReleaseReaderLock();
}
public void write()
{
rw.AcquireWriterLock(Timeout.Infinite);
for (int j = 0; j < 10; j++)
{
Thread.Sleep(20);
Console.WriteLine(Thread.CurrentThread.Name + " write " + i++);
}
rw.ReleaseWriterLock();
}
}
}