多线程编程面试题
https://www.cnblogs.com/anding/p/5301754.html
1.描述线程与进程的区别?
*一个应用程序实例是一个进程,一个进程包含一个或多个线程,线程是进程的一部分;
*进程之间是相互独立的,它们有各自的私有内存空间和资源,进程内的线程可以共享其所属进程的所有资源;
2.为什么GUI不支持跨线程访问控件?一般如何解决这个问题?
因为GUI应用程序引入了一个特殊的线程处理模型,为了保证UI控件的线程安全,这个线程处理模型不允许其他子线程跨线程访问UI元素。解决方法还是比较多的,如:
*利用UI控件提供的方法,Winform是控件的Invoke方法,WPF中是控件的Dispatcher.Invoke方法;
*使用BackgroundWorker;
*使用GUI线程处理模型的同步上下文SynchronizationContext来提交UI更新操作。
3.简述后台线程和前台线程的区别?
应用程序必须运行完所有的前台线程才可以退出,或者主动结束前台线程,不管后台线程是否还在运行,应用程序都会结束;而对于后台线程,应用程序则可以不考虑其是否已经运行完毕而直接退出,所有的后台线程在应用程序退出时都会自动结束。
4.说说常用的锁,lock是一种什么样的锁?
常用的锁有SemaphoreSlim,ManualResetEventSlim,Monitor,ReadWriteLockSlim,lock是一个混合锁,其实质是Monitor[].
5.lock为什么要锁定一个参数,可不可以锁定一个值类型?这个参数有什么要求?
lock的锁对象要求为一个引用类型。它可以锁定值类型,但值类型会被装箱,每次装箱后的对象都不一样,会导致锁定无效。
对于lock锁,锁定的这个对象参数才是关键,这个参数的同步索引块指针会指向一个真正的锁(同步块),这个锁(同步块)会被复用。
6.多线程和异步有什么关系和区别?
多线程是实现异步的主要方式之一,异步并不等于多线程。实现异步的方式还有很多,比如利用硬件的特性、使用进程或线程等。在.NET中就有很多的异步编程支持,比如很多地方都有Begin****,End**的方法,就是一种异步编程支持,它内部有些是利用多线程,有些是利用硬件的特性来实现的异步编程。
7.线程池的优点有哪些?又有哪些不足?
优点:减小线程创建的销毁的开销,可以重复使用线程;也从而减少了线程上下文切换的性能损失;在GC回收时,较少的线程更有利于GC的回收效率。
缺点:线程池无法对一个线程有更多的精确的控制,如了解其运行状态等;不能设置线程的优先级;加入到线程池的任务不能有返回值;对于需要长期运行的任务就不适合线程池。
8.Mutex和lock有何不同?一般用哪一个作为锁使用更好?
Mutex是一个基于内核模式的互斥锁,支持锁的递归调用,而Lock是一个混合锁,一般建议使用Lock更好,因为lock的性能更好。
9.下面的代码,调用方法DeadLockTest(20),是否会引起死锁?并说明理由?
public void DeadLockTest(int i)
{
lock(this) //或者lock一个静态object变量
{
if(i > 10)
{
Console.WriteLine(i–);
DeadLockTest(i);
}
}
}
不会的,因为lock是一个混合锁,支持锁的递归调用,如果你使用一个ManualResetEvent或AutoResetEvent可能就会发生死锁。
10.用双检锁实现一个单例模式Singleton.
public static class Singleton where T : class,new()
{
private static T _Instance;
private static object _locjObj = new object();
public static T GetInstance()
{
if(_Instance != null)
{
return _Instance;
}
lock(_locjObj)
{
if(_Instance == null)
{
var temp = Activator.CreateInstance<T>();
System.Threading.Interlocked.Exchange(ref _Instance,temp);
}
}
return _Instance;
}
}