博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
深入浅出多线程系列之一:简单的Thread
阅读量:5143 次
发布时间:2019-06-13

本文共 1698 字,大约阅读时间需要 5 分钟。

CLR和操作系统会自动的为应用程序创建一个线程,这个线程叫做主线程(main Thread)

如果要创建一个新的线程,可以使用Thread类。下面是一个简单的例子:

class
 ThreadTest
{
  
static
 
void
 Main()
  {
    Thread t 
=
 
new
 Thread (WriteY);          
//
 创建一个新的线程来执行WriteY方法
    t.Start();                               
//
 开始运行 WriteY()
    
//在主线程上模拟的做些事情.
 
    
for
 (
int
 i 
=
 
0
; i 
<
 
1000
; i
++
) Console.Write (
"
x
"
);
  }
  
static
 
void
 WriteY()
  {
    
for
 (
int
 i 
=
 
0
; i 
<
 
1000
; i
++
) Console.Write (
"
y
"
);
  }
}

首先创建了一个线程来执行WriteY方法,然后调用Start()来启动创建的线程,接着在主线程中用for循环输出“x”。

很容易就知道答案:例如XXXXYYYYXXXXXYYYYYXXXXYYYYYYYYYYYYYYYYYYYXXXXXXXXXXXXXXX

X和y间隔的出现。

一旦线程启动了,线程的IsAlive属性在线程结束前就会返回True,当传递给线程的构造函数中的委托执行完毕,线程就结束了,一旦线程结束了,线程是不可能再重新启动的。

CLR为每一个线程分配独立的内存栈,这样就可以保证局部变量隔离。下面是使用局部变量的例子。

class
 ThreadTest
    {
        
bool
 done;
        
public
 
static
 
void
 Main()
        {
            ThreadTest tt 
=
 
new
 ThreadTest();
            
new
 Thread(tt.Go).Start();
            tt.Go();
        }
        
void
 Go()
        {
            
if
 (
!
done)
            {
                done 
=
 
true
;
                Console.WriteLine(
"
Done
"
);
            }
        }
    }

因为new Thread(tt.Go) 和tt.Go方法都共享tt的done字段。

所以Console.WriteLine("Done")会且只会被执行一变。

我们修改下上面的代码,修改后如下:

class
 ThreadTest
    {
        
static
 
bool
 done; //静态变量被所有的线程共享
        
public
 
static
 
void
 Main()
        {
            
new
 Thread(Go).Start();
            Go();
        }
        
static
 
void
 Go()
        {
            
if
 (
!
done)
            {
                done 
=
 
true
;
                Console.WriteLine(
"
Done
"
);
            }
        }
    }

问题来了,Console.WriteLine会被执行几遍?

有些同学会说一遍,有些同学会说两遍,其实答案很简单:有时候一遍,有时候两遍。

因为静态变量会被所有线程共享,

执行一遍的就不解释了,比较简单。

执行两遍:线程A执行到if(!done) 此时done为false。所以通过if判断,在同时线程B也执行到了if(!done)此时done也为false,所以也通过了判断。

如果你把上面的Go代码调整到下面的样子,出现两次的概率就会变大很多。

static
 
void
 Go()
        {
            
if
 (
!
done)
            {
                
//
两个线程都到了这里
                Console.WriteLine(
"
Done
"
);
                done 
=
 
true
;
            }
        }

这种现象就叫做线程安全,或者说缺少线程安全。后续文章会慢慢介绍。

 

谢谢楼下的同学的建议:

下面做下解释: 

虽然new Thread(tt.Go) 和tt.Go方法都共享tt的done字段,但是两个线程可能都通过了if判断,

所以Console.WriteLine方法可能会被执行两遍.

 

参考资料:

CLR Via C# 3.0

转载于:https://www.cnblogs.com/LoveJenny/archive/2011/05/21/2049300.html

你可能感兴趣的文章
队列-生产者消费者模式
查看>>
学习笔记23_AspMVC项目
查看>>
webstrom提示不见了
查看>>
Linux 永久挂载镜像文件和制作yum源
查看>>
Lock和synchronized比较详解(转)
查看>>
eclipse代码编辑器中按alt+/提示No Default Proposals 的解决方法
查看>>
相似算法-编辑距离
查看>>
hql date比较
查看>>
前端如何判断音视频是否播放完毕
查看>>
[转]vi 常用命令行
查看>>
php服务器端检查手机访问还是pc访问(并跳到不同页面)
查看>>
WPF快速入门系列(3)——深入解析WPF事件机制
查看>>
【消息队列】 RabbitMQ教程汇总
查看>>
eclipse远程连接hive
查看>>
2011-4-12学习总结
查看>>
VS单元测试"未能加载文件或程序集,或它的某一个依赖项"
查看>>
20145322 20145310 20145318信息安全系统设计基础实验报告
查看>>
Netty——高级发送和接收数据handler处理器
查看>>
如何查看JSP和Servlet版本
查看>>
【Finish】Python Day 9
查看>>