两种新建线程的简单方法以及懒汉模式中lock的重要性
来源:互联网 发布:java程序员到架构师 编辑:程序博客网 时间:2024/06/08 09:51
先扔代码吧。。。
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;using System.Threading.Tasks;//Parallel类namespace ThreadDemo{ class Program { static void Main(string[] args) { ThreadDemo[] array = new ThreadDemo[10]; for (int i = 0; i < 10; i++) //array[i] = new CreateOnlyOneThread(); array[i] = new CreateOnlyOneInvoke(); Parallel.ForEach(array, i => i.Start()); Console.ReadLine(); } } interface ThreadDemo { void Start(); } class CreateOnlyOneThread : ThreadDemo { private Thread thread; private delegate void CreateOnlyOneThreadMethod(); public void GetOnlyOne() { OnlyOne.GetOnlyOne(); } public void Start() { CreateOnlyOneThreadMethod createOnlyOneThreadMethod = GetOnlyOne; thread = new Thread(new ThreadStart(createOnlyOneThreadMethod)); thread.IsBackground = true; thread.Start(); } } class CreateOnlyOneInvoke : ThreadDemo { IAsyncResult iar; private delegate void CreateOnlyOneInvokeMothed(); public void GetOnlyOne() { OnlyOne.GetOnlyOne(); } public void Start() { CreateOnlyOneInvokeMothed createOnlyOneInvokeMothed = GetOnlyOne; iar = createOnlyOneInvokeMothed.BeginInvoke(null, null); } } class OnlyOne { private static OnlyOne onlyone; private static object obj= new object(); private OnlyOne() { Console.WriteLine("Create!"); } public static OnlyOne GetOnlyOne() { if (onlyone==null) lock(obj) { if (onlyone==null) onlyone=new OnlyOne(); } return onlyone; } }}
上面的代码中CreateOnlyOneThread类和CreateOnlyOneInvoke类分别是两种新建线程的方法,感觉都挺好上手的,但是他们都有一个共同的特点就是要用委托。
但是效果上有点不同
BeginInvoke方法创造出来的子线程可以理解为 他的IsBackGround为True,也就是说如果主线程(这里面是Main)结束的话,不管子线程有没有执行完毕都会退出。
而Thread,Start()的线程是可以调的,如果IsBackGround为false,那么即使主线程结束,仍然会等待子线程结束。
但是如果做得不是控制台而是Windows程序的话,这种情况直接alt+F4,打开任务管理器发现进程仍然还在!
然后再说下lock的事。。。
一般都是用lock(this)的。。。但是由于是静态方法,所以只能新建一个静态的object对象。
第一层是判断当前是否已经创建OnlyOne的对象,如果没有创建,那么向下执行。
然后问题来了,既然已经锁住了,那么还加一层判断干什么?这正是多线程麻烦的地方。。。
如果一个线程,我们大概可以在脑中模拟出程序执行的过程,但是如果是多线程的话,就不一样了。。。因为即使是只添加一个线程,程序运行的结果就已经不能预测得到的了。所以一般调多线程的程序都不用debug。。。
回到主题,打个比方,有一个400米赛跑比赛,比赛规定:1、如果有人完成比赛,那么设在100米检查点(也就是第一个 if (onlyOne==null) )就禁止选手通过(就是对象已经穿件完毕,不用在创建了)。2、如果有人已经通过了200米检查点,那么其他选手要在200检查点处等待,直到那个通过200,米检查点的选手完成比赛,才允许下一个选手通过200米检查点(也就是lock(obj){}的那块)。
如果是普通的单线程的话,就是第一个人先跑,跑到终点之后第二个再跑。这样按照规则,因为第一个人已经完成了比赛,所以第二个,第三个,以及他们后面的都无法通过100米的检查点。但是现在不同,现在是所有人一起跑,所以当有人第一个通过终点前肯定也有人已经也跑过了100米的检查点,这个时候大家来到了200米的检查点,由于先前通过200米检查点的人没有通过终点,所以大家(众线程)只好等待(这个也就是lock的作用),直到那个人通过重点(创建完对象,解锁),才会有下一个人通过200米检查点。这个时候第二个 if (onlyOne==null) 的作用就体现出来了,如果之前没有创建,那么onlyOne为null,创建对象,如果不为null,说明已经创建完,不再创建。这样才算是只创建了一个对象。
所以无论是写什么样的代码,一旦涉及多线程,一定要多运行几次,看看会不会出错误,因为多线程的随机化真的很难预测。
- 两种新建线程的简单方法以及懒汉模式中lock的重要性
- 黑马程序员笔记:单例模式的简单实现与两种实现方法的比较(饿汉式和懒汉式)(一)
- 黑马程序员笔记:单例模式的简单实现与两种实现方法的比较(饿汉式和懒汉式)(二)
- 单例模式的两种方式:懒汉式、饿汉式
- Android Studio中新建assets文件的两种方法
- Hibernate5.x中新建SessionFactory的两种方法
- 懒汉式单例模式的线程安全问题
- java中开辟新线程的两种方法以及区别
- 关于多线程在简单的懒汉模式下线程安全问题的解决
- 单例模式的两种方式:饿汉模式与懒汉模式
- 单例模式之懒汉模式的线程安全解决方法
- 懒汉和饿汉单例模式以及单例模式的概念
- Java新建线程的3种方法
- Java新建线程的3种方法
- 线程的两种方法
- 单例模式--饿汉式、懒汉式、线程安全的懒汉式、高性能安全的懒汉式
- 简单java单例模式 懒汉式、饿汉式以及解决线程安全问题(synchronized)
- Qt新建线程的方法
- java实现 n阶幻方(奇偶通用)
- Linux进程 进程组 会话 控制终端概念
- Linq to XML Helper
- Undefined reference to 'WinMain@16
- Redis主从同步—笔记
- 两种新建线程的简单方法以及懒汉模式中lock的重要性
- iOS之优先使用autorelease
- Mongoose入门
- cannot set user id Resource temporarily unavailable
- 6572 Phone call分析
- 详谈ASP.NET的DataReader对象
- Android 之 尺寸的国际化
- Dos命令行中怎么向Java程序传递参数
- 黑马程序员 C#中的var