笔试题多线程

摘要:
多线程是实现异步的主要方式之一,异步不等于多线程。NET有很多异步编程支持。例如,Begin***和End***方法在许多地方都可用,这是一种异步编程支持。它的一些内部程序是使用多线程的异步编程,而其他程序是使用硬件功能的异步编程。因为多线程访问不使用锁定机制,所以更新将丢失。

1. 描述线程与进程的区别?

  • 一个应用程序实例是一个进程,一个进程内包含一个或多个线程,线程是进程的一部分;
  • 进程之间是相互独立的,他们有各自的私有内存空间和资源,进程内的线程可以共享其所属进程的所有资源;

2. 为什么GUI不支持跨线程访问控件?一般如何解决这个问题?

因为GUI应用程序引入了一个特殊的线程处理模型,为了保证UI控件的线程安全,这个线程处理模型不允许其他子线程跨线程访问UI元素。解决方法还是比较多的,如:

  • 利用UI控件提供的方法,Winform是控件的Invoke方法,WPF中是控件的Dispatcher.Invoke方法;
  • 使用BackgroundWorker;
  • 使用GUI线程处理模型的同步上下文SynchronizationContext来提交UI更新操作

上面几个方式在文中已详细给出。

3. 简述后台线程和前台线程的区别?

应用程序必须运行完所有的前台线程才可以退出,或者主动结束前台线程,不管后台线程是否还在运行,应用程序都会结束;而对于后台线程,应用程序则可以不考虑其是否已经运行完毕而直接退出,所有的后台线程在应用程序退出时都会自动结束。

通过将 Thread.IsBackground 设置为 true,就可以将线程指定为后台线程,主线程就是一个前台线程。

4. 说说常用的锁,lock是一种什么样的锁?

常用的如如SemaphoreSlim、ManualResetEventSlim、Monitor、ReadWriteLockSlim,lock是一个混合锁,其实质是Monitor['mɒnɪtə]。

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<T> where T : class,new()
    {
        private static T _Instance;
        private static object _lockObj = new object();

        /// <summary>
        /// 获取单例对象的实例
        /// </summary>
        public static T GetInstance()
        {
            if (_Instance != null) return _Instance;
            lock (_lockObj)
            {
                if (_Instance == null)
                {
                    var temp = Activator.CreateInstance<T>();
                    System.Threading.Interlocked.Exchange(ref _Instance, temp);
                }
            }
            return _Instance;
        }
    }

11.下面代码输出结果是什么?为什么?如何改进她?

int a = 0;
System.Threading.Tasks.Parallel.For(0, 100000, (i) =>
{
    a++; 
});
Console.Write(a);

输出结果不稳定,小于等于100000。因为多线程访问,没有使用锁机制,会导致有更新丢失。具体原因和改进在文中已经详细的给出了。

免责声明:文章转载自《笔试题多线程》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇jenkins之部署、启动、关闭tomcat不打印日志的原因及解决办法下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Unity应用架构设计(10)——绕不开的协程和多线程(Part 2)

在上一回合谈到,客户端应用程序的所有操作都在主线程上进行,所以一些比较耗时的操作可以在异步线程上去进行,充分利用CPU的性能来达到程序的最佳性能。对于Unity而言,又提供了另外一种『异步』的概念,就是协程(Coroutine),通过反编译,它本质上还是在主线程上的优化手段,并不属于真正的多线程(Thread)。那么问题来了,怎样在Unity中使用多线程呢...

Java多线程——Condition条件

简介 Condition中的await()方法相当于Object的wait()方法,Condition中的signal()方法相当于Object的notify()方法,Condition中的signalAll()相当于Object的notifyAll()方法。 不同的是,Object中的wait(),notify(),notifyAll()方法是和"同步锁...

多线程之旅六——异步编程模式,自己实现IAsyncResult

作为模式,只是一种大家认可的经验,模式可以作为大家交流的词汇而存在。下面我们就要介绍几种异步编程模式,AMP、EAP和TAP。当然,法无定法,在我们理解的基础上,我们可以根据具体情况适度修改。下面介绍的只是在通常情况下的两种模式会是以什么样子的形式出现。   一 模型简介 1.APM 异步编程模型 这种模式的特征是一些成对出现的方法,分别以Begin和En...

浅析.Net下的多线程编程(1)

作者:peter 出处:天极论坛 多线程是许多操作系统所具有的特性,它能大大提高程序的运行效率,所以多线程编程技术为编程者广泛关注。 目前微软的.Net战略正进一步推进,各种相关的技术正为广大编程者所接受,同样在.Net中多线程编程技术具有相当重要的地位。本文我就向大家介绍在.Net下进行多线程编程的基本方法和步骤。 开始新线程 在.Net下创建一个新线...

转:WaitForSingleObject()函数、WaitForMultipleObject()函数

http://blog.csdn.net/xiaobai1593/article/details/6672193 在多线程下面,有时候我们会希望等待某一线程完成了再继续做其他事情,要实现这个目的,可以使用Windows API函数WaitForSingleObject,或者WaitForMultipleObjects。这两个函数都会等待Object被标为有...

Qt 学习之路 2(75):线程总结

前面我们已经详细介绍过有关线程的一些值得注意的事项。现在我们开始对线程做一些总结。 有关线程,你可以做的是: 在QThread子类添加信号。这是绝对安全的,并且也是正确的(前面我们已经详细介绍过,发送者的线程依附性没有关系) 不应该做的是: 调用moveToThread(this)函数 指定连接类型:这通常意味着你正在做错误的事情,比如将QThread控...