美文网首页Java 杂谈
多线程面试题总结

多线程面试题总结

作者: _云起 | 来源:发表于2018-12-13 20:27 被阅读36次

    1、什么是线程,什么是进程,它们有什么区别和联系,一个进程里面是否必须有个线程

            进程本质是一个正在执行的程序,一个进程可以有多个线程.线程是进程的最小执行单位,一个进程至少有一个线程

    区别:1:多进程程序不受java控制,而多线程则受java控制,

            2:多线程比多进程需要更少的管理成本

    2、实现一个线程有哪几种方式,各有什么优缺点,比较常用的是那种,为什么

            实现一个线程有三种方式:

    1)      继承Thread类,需要重写run方法,无返回值

    a)        优点:可以直接调用start方法启动线程

    b)        缺点:java只能单继承,如果已经有了父类,不能用这种方法

    2)      实现Runnable接口,需要重写run()方法

    a)        优点:即使自己定义的线程类有了父类也可以实现接口,而且接口是多实现

    b)        缺点:需通过构造一个Thread把自己传进去,才能实现Thread的方法,代码复杂

    3)      实现Callable接口,需要重写call()方法

    a)        优点:可以抛出异常,有返回值

    b)        缺点:只有jdk1.5以后才支持,结合FuntureTask和Thread类一起使用,最后调用start启动线程

    一般用第二种,实现Runnable接口,比较方便,扩展性高

    3、一般情况下我们实现自己线程时候要重写什么方法

            使用Thread类,要重写run()方法

            实现Runnable接口时,要实现run()方法

            使用Callable接口时,要重写call()方法

    4、start方法和run方法有什么区别,我们一般调用的那个方法,系统调用的是那个方法

            Start用来启动线程

            当调用start后,线程并不会马上运行,而是处于就绪状态,是否要运行取决于cpu

            Run用来子类重写来实现线程的功能

            我们一般调用的是start方法,系统调用的是run方法

    5、sleep方法有什么作用,一般用来做什么

            Sleep是一个Thread类的静态方法

            作用:让调用它的线程休眠指定的时间,用于暂停线程,但不会把线程锁让给其它线程,休眠时间结束,线程进入就绪状态,等待cpu分配的执行机会

    6、讲下join,yield方法的作用,以及什么场合用它们

            Join()有严格的先后顺序,调用它的线程需要执行完,其它线程才会执行

            Yield()是暂停当前正在执行的线程对象,把时间让给其它线程

    7、线程中断是否能直接调用stop,为什么?

            线程终端不能直接调用stop()方法

            Stop()方法是从外部强行终止一个线程,会导致不可预知的错误,比如线程锁没有归还,io流不能关流        线程只能调用interrupt()方法中断,而且不是立即中断,     只是发出了一个类似于信号量的东西,通过修改了被调用线程的中断状态来告知那个线程,说它被中断了,至于什么时候中断,这个系统会判断)系统会在一个合适的时候进行中断处理

    8、列举出一般情况下线程中断的几种方式,并说明他们之间的优缺点,并且说明那种中断方式最好

            线程中断有4种方式

    由interrupt发出中断信号,用户接收中断信号,通过isInterrupted判断线程是否中断

    由interrupt发出中断信号,系统接收中断信号,通过sleep抛出中断异常,并把中断信号清除,只能抛出一次

    用户自定义中断,将中断信号发出,自己接收该中断信号

    调用interrupted(),会把中断信号清除,并中断线程

    9、线程有几种状态,他们是怎么转化的

            线程一般分为:新生,就绪,运行,阻塞,死亡五中状态

            当创建一个线程后,并没有运行,处于新生状态,需要通过调用start方法,让线程处于就绪状态,但是否运行取决于cpu分配的执行机会,当得到cpu的执行机会后马上运行,一个正在执行的线程可以通过很多方式进入阻塞状态,当执行完所有操作后就进入死亡状态

    10、在实现Runnable的接口中怎么样访问当前线程对象,比如拿到当前线程的名字

            通过Thread.currentThread().getName()可获得当前线程名字

    11、讲下什么是守护线程,以及在什么场合来使用它   

    守护线程是用来监听其它线程是否挂掉,这个线程具有最低优先级

    用于为系统中的其它线程提供服务

    守护线程就像象棋里的车马相仕,非守护线程就是老帅,老帅挂掉,守护线程也就挂掉了

            当主线程和主线程创建的子线程全部退出,守护线程一定会跟着退出

            (比如QQ主程序和QQ聊天窗口,主程序退出,QQ聊天窗口也随之关掉)

    12、一般的线程优先级是什么回事,线程优先级高的线程一定会先执行吗?如果不设置优先级的话,那么线程优先级是多少,设置线程优先级用那个函数

            线程的优先级就是设置哪个线程先执行,但不是绝对,只是让优先级高的线程优先运行的概率高一些,

            线程默认优先级是NORM_PRIORITY = 5;

            最小是 MIN_PRIORITY = 1;

            最大是 MAX_PRIORITY = 10;

            设置线程优先级有setPriority()方法

    13、为什么Thread里面的大部分方法都是final的

            线程很多方法都是由系统调用的,不能通过子类重写去改变他们的行为

    14、什么是线程同步,什么是线程安全

            同步:当两个或两个以上的线程需要共享资源,通过同步方法限制资源在一次仅被一个线程占用

            线程安全:线程安全就是多线程操作同一个对象不会产生数据污染,

            线程同步一般来保护线程安全,final修饰的也是线程安全

    15、讲下同步方法和同步块的区别,以及什么时候用它们

            同步方法:被synchronized修饰的方法,同步整个方法,且整个方法都会被锁住,同一时间只有一个线程可以访问该方法,

            同步块: 被synchronized修饰的代码块,可以同步一小部分代码

    什么时候用?

            同步块越小性能越好,当性能要求比较高,用同步代码块

    16、简单说下Lock对象的实现类的锁机制和同步方法或同步块有什么区别

            是JDK1.5才出现的,Lock对象比synchronized更加灵活,可以控制什么时候上锁,什么时候解锁,而使用synchronized必须等代码执行完才会解锁.

           Synchronized在锁定时如果方法块抛出异常,JVM会自动释放锁,而Lock出现异常必须在finally将锁释放,否则将引起死锁

    17、同步块里面的同步监视器是怎么写的,默认的同步方法里面的同步监视器是那个

            Synchronized(对象){

                            //代码块

            }

           默认的同步监视器是this

    18、讲下什么是死锁,死锁发生的几个条件是什么

            死锁就是当有两个或两个以上的线程都获得对方的资源,但彼此都不肯放开,处于僵持阶段,此时就造成了死锁

            条件:两个或两个以上的线程,同时想要获得对方的资源,彼此又不肯放开

    19、线程间是怎么通信的,通过调用几个方法来交互的

            线程是通过wait , notify等方法相互作用进行协作通信;

            wait()方法使得当前线程必须要等待,直到到另外一个线程调用notify()或者notifyAll()方法唤醒

            -- wait()和notify()方法要求在调用时线程已经获得了对象锁,因此对这两个方法的调用需要放           在  synchronized修饰的方法或代码块中。

    20、wait,notify,notifyAll在什么地方使用才有效,他们是那个类的方法

            Wait,notify,notifyAll都必须在synchronized修饰的方法或代码块中使用,都属于Object的方法,可以被所有类继承,都是final修饰的方法,不能通过子类重写去改变他们的行为

    21、wait和sleep有什么区别和联系,他们执行的时候是否都会释放锁

            Wait和sleep都可以使线程暂停,但wait必须在synchronized修饰的方法或代码块中使用,

           Sleep()方法是线程类的静态方法,调用此方法会让当前线程暂停执行指定的时间,将执行机会(CPU)让给其它线程,但是对象的锁依然保持,因此休眠时间结束后会自动恢复(就绪状态),

           wait()是Object类的方法,调用对象的wait()方法会让当前线程放弃对象的锁(线程暂停执行),进入对象的等待池(wait pool),只有调用对象的Notify()或notifyAll()方法才能唤醒等待池中的线程进入等锁池(lock pool),如果线程重新获得对象的锁就可以进入就绪状态

    22、yield,sleep方法有什么区别和联系

            Yield和sleep都可以让线程暂停,

    1)      Sleep()方法给其它线程运行机会时不考虑线程的优先级,因此会给低优先级的线程以运行机会…yield()方法只会给相同优先级或更高优先级的线程以运行机会

    2)      线程执行sleep()方法后转入阻塞状态,而执行yield()方法后转入就绪状态

    3)      Sleep()方法声明抛出InterruptedException,而yield()方法没有声明任何异常

    4)      Sleep()方法比yield()方法具有更好的可移植性

    23、线程的启动是哪个方法,调用的是哪个方法?

            Start用于启动线程,当调用start后,线程并不会马上运行,而是处于就绪状态,是否运行取决于cpu给的时间片

            Run()方法用于子类重写来实现线程的功能

            我们一般调用的是start方法,系统调用的是run方法

    24、线程安全与线程不安全的区别

                  线程安全就是多线程访问时,采用了加锁机制,

                  当一个线程访问类中某个数据,进行保护,其它线程不能进行访问,直到该线程执行完,其它线程才可使用---不会导致数据污染

                  线程不安全就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据

    25、线程的实现方式,线程的生命周期等

                  实现方式

    1)  通过继承Thread类

    2)  实现Runnable接口

    3)  实现Callable接口

                  生命周期

                  新建

                  就绪

                  运行

                  堵塞

                  死亡

    26、如何处理线程不安全问题(有2种解决方法)

                  第一,是采用原子变量,线程安全问题最根本上是由于全局变量和静态变量引起的,定义变量用sig_atomic_t和volatile。

                  第二,就是实现线程间同步,让线程有序访问变量

    27、线程中常用方法的区别

                  线程中用到最多的是start方法,它的作用是启动一个线程

                  Sleep()让线程休眠一会,但不会释放锁

                  Join()强制执行一个线程

                  Wait()是Object类中的方法,会让当前线程放弃对象锁,进入对象等待池

                  Yield()礼让线程,让另外一个线程执行一会,自己再执行,只能让同优先级的线程有执行的机会

                  currentThread()用于获得当前线程对象,可以调用getName()方法获得当前线程名字

    28、多线程和单线程有什么区别?

            干一件事情一个人干和两个人同时干的区别

    29、线程的5种状态,__、_、_、___。启动调用_方法,启动后会调用__方法。

                  新生

                  就绪

                  运行

                  阻塞

                  死亡

                  启动调用start()

    30、用同步块与同步方法的区别?

                  同步方法是被synchronized修饰的方法,同步整个方法, ,同一时间只有一个线程可以访问该                   方法

                  同步块是被synchronized修饰的代码块,可以同步一小部分代码           

                  同步代码越少性能越好,当性能要求比较高时,用同步块     

    31、什么是同步和异步,分别用例子说明,同步有几种方式?

            同步是排队去做事情,异步就是各做各的

    32、什么是对象锁?

    1.  java中的每个对象都有一个锁,当访问某个对象的synchronized方法时,表示将该对象上锁,此时其他任何线程都无法在去访问该syncronized 方法了,直到之前的那个线程执行方法完毕后,其他线程才有可能去访问该synchronized方法。

    2.如果一个对象有多个synchronized方法,某一时刻某个线程已经进入到某个synchronzed方法,那么在该方法没有执行完毕前,其他线程无法访问该对象的任何synchronzied 方法的,但可以访问非synchronzied方法。

    3.如果synchronized方法是static的,那么当线程访问该方法时,它锁的并不是synchronized方法所在的对象,而是synchuronized方法所在对象的对应的Class对象,

            [类锁(synchronized修饰的静态方法)]

    33、什么是死锁?

           死锁就是当有两个或两个以上的线程都获得对方的资源,但彼此有不肯放开,处于僵持状态,此时便造成了死锁。

    相关文章

      网友评论

        本文标题:多线程面试题总结

        本文链接:https://www.haomeiwen.com/subject/jixihqtx.html