JAVA多线程面试题整理及答案

什么是线程,进程?

进程:进程就是一段程序的执行过程,进程是表示资源分配的基本单位,又是调度运行的基本单位.进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元线程:线程是进程中执行运算的最小单位,亦即执行处理机调度的基本单位,一个进程可以包含多个线程,至少是一个线程线程是进程的子集,一个进程可以有很多线程,每条线程并行执行不同的任务。每个进程所能访问的内存是互相独立的(一些交换区除外)。而进程中的线程所以共享进程所分配的内存空间.

如何在Java中实现线程?

java.lang.Thread 类的实例就是一个线程但是它需要调用java.lang.Runnable接口来执行,由于Thread类本身就是调用的Runnable接口所以你可以继承 java.lang.Thread 类或者直接调用Runnable接口来重写run()方法实现线程

Thread
Thread thread = new Thread() {@Overridepublic void run() {System.out.println("Thread started!");
} };
thread.start();
Runnable
Runnable runnable = new Runnable() {@Overridepublic void run() {System.out.println("Thread with Runnable started!");
} };
Thread thread = new Thread(runnable);
thread.start();
使用Thread还是Runnable

Runnable是一个接口.而Thread是一个实现了Runnable接口的类,在JAVA中是不允许多继承的,但是可以实现多个接口.如果你的类既需要继承其他的类又需要实现多线程,就需要实现runnable接口了

Thread 类中的start() 和 run() 方法有什么区别

start()方法被用来启动新创建的线程,而且start()内部 调用了run()方法,这和直接调用run()方法的效果不一样。当你调用run()方法的时候,只会是在原来的线程中调用,没有新的线程启 动,start()方法才会启动新线程。

JAVA中Runnable和Callable有什么不同?

Runnable和Callable都代表那些要在不同的线程中执行的任务。Runnable从JDK1.0开始就有了,Callable是在 JDK1.5增加的。它们的主要区别是Callable的 call() 方法可以返回值和抛出异常,而Runnable的run()方法没有这些功能。Callable可以返回装载有计算结果的Future对象。但是如果callable没有执行完的话,调用Future.get()是会堵塞线程的

线程同步与线程安全

什么是线程安全?
如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。

在多个线程访问共同的资源时,在某⼀一个线程对资源进⾏行行写操作的中途(写⼊入已经开始,但还没 结束),其他线程对这个写了了⼀一半的资源进⾏行行了了读操作,或者基于这个写了了⼀一半的资源进⾏行行了了写 操作,导致出现数据错误。

synchronized
  • 保证方法内部或代码块内部资源(数据)的互斥访问。即同一时间、由同⼀个 Monitor 监视的代码,最多只能有一个线程在访问
  • 保证线程之间对监视资源的数据同步。即,任何线程在获取到 Monitor 后的第⼀时 间,会先将共享内存中的数据复制到⾃己的缓存中;任何线程在释放 Monitor 的第一 时间,会先将缓存中的数据复制到共享内存中。
同步方法,同步代码块synchronized(object) synchronized(class) ,静态同步方法的区别。
  • 同步方法,同步代码块synchronized(object)
    这两种的写法的效果是一致的,当一个线程对synchronized(object)进行访问时,其他线程对synchronized(object)和对同一个object锁的其 他synchronized(object)进行访问都将会堵塞
  • synchronized(class) 静态同步方法
    这两种的写法的效果是一致的,同步synchronized(*.class)代码块的作用其实和synchronized static方法作用一样。Class锁对类的所有对象实例起作用。
    详细分析见 https://blog.csdn.net/luckey_zh/article/details/53815694
volatile
  • 保证加了 volatile 关键字的字段的操作具有原子性和同步性,其中原⼦性相当于实现了针对 单一字段的线程间互斥访问。因此 volatile 可以看做是简化版的 synchronized。

  • volatile 只对基本类型 (byte、char、short、int、long、float、double、boolean) 的赋值操作和对象的引用赋值操作有效 ,只对赋值操作有效,自增自减等无效,还是需要用synchronized和lock

  • 禁止指令重排序

    1. 当程序执行到volatile变量的读操作或者写操作时,在其前面的操作的更改肯定全部已经进行,且结果已经对后面的操作可见;在其后面的操作肯定还没有进行

    2. 在进行指令优化时,不能将在对volatile变量访问的语句放在其后面执行,也不能把volatile变量后面的语句放到其前面执行

      //x、y为非volatile变量
      //flag为volatile变量x = 2;        //语句1
      y = 0;        //语句2
      flag = true;  //语句3
      x = 4;         //语句4
      y = -1;       //语句5
      

      由于flag变量为volatile变量,那么在进行指令重排序的过程的时候,不会将语句3放到语句1、语句2前面,也不会讲语句3放到语句4、语句5后面。但是要注意语句1和语句2的顺序、语句4和语句5的顺序是不作任何保证的。

什么是竞态条件?
如果程序运行顺序的改变会影响最终结果,这就是一个竞态条件

Java多线程中调用wait() 和 sleep()方法有什么不同?

Java程序中wait 和 sleep都会造成某种形式的暂停,它们可以满足不同的需要。wait()方法调用会释放锁,而 sleep()方法仅仅释放CPU资源或者让当前线程停止执行一段时间,但不会释放锁。

如何终止线程

stop和interrupt()

stop强行结束,

interrupt是温和的结束,标记线程结束的状态,不立即,不强制.需要被终结的线程支持 才能使用interrupt.

Thread.interrupted()和thread.isInterrupted()的区别
  • Thread.interrupted()在获取线程中断状态为true后,会重置线程中断状态,也就是把中断状态变为false。
  • thread.isInterrupted(),只是单纯的获取中断线程状态,不会重置。

sleep(),wait(),notify(),notifyAll(), join(),yield()

  • sleep()

    sleep()方法需要指定等待的时间,它可以让当前正在执行的线程在指定的时间内暂停执行,进入阻塞状态,该方法既可以让其他同优先级或者高优先级的线程得到执行的机会,也可以让低优先级的线程得到执行机会。但是sleep()方法不会释放“锁标志”,也就是说如果有synchronized同步块,其他线程仍然不能访问共享数据。

  • wait()

    wait()方法需要和notify()及notifyAll()两个方法一起介绍,这三个方法用于协调多个线程对共享数据的存取,所以必须在synchronized语句块内使用,也就是说,调用wait(),notify()和notifyAll()的任务在调用这些方法前必须拥有对象的锁。注意,它们都是Object类的方法,而不是Thread类的方法。   wait()方法与sleep()方法的不同之处在于,wait()方法会释放对象的“锁标志”。当调用某一对象的wait()方法后,会使当前线程暂停执行,并将当前线程放入对象等待池中,直到调用了notify()方法后,将从对象等待池中移出任意一个线程并放入锁标志等待池中,只有锁标志等待池中的线程可以获取锁标志,它们随时准备争夺锁的拥有权。当调用了某个对象的notifyAll()方法,会将对象等待池中的所有线程都移动到该对象的锁标志等待池。   除了使用notify()和notifyAll()方法,还可以使用带毫秒参数的wait(long timeout)方法,效果是在延迟timeout毫秒后,被暂停的线程将被恢复到锁标志等待池。   此外,wait(),notify()及notifyAll()只能在synchronized语句中使用,但是如果使用的是ReenTrantLock实现同步,该如何达到这三个方法的效果呢?解决方法是使用ReenTrantLock.newCondition()获取一个Condition类对象,然后Condition的await(),signal()以及signalAll()分别对应上面的三个方法。

  • yield()

    yield()方法和sleep()方法类似,也不会释放“锁标志”,区别在于,它没有参数,即yield()方法只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行,另外yield()方法只能使同优先级或者高优先级的线程得到执行机会,这也和sleep()方法不同。

  • join()

    join()方法会使当前线程等待调用join()方法的线程结束后才能继续执行

线程的优先级

线程总是存在优先级,**优先级范围在1~10之间**,可以通过**setPriority(int newPriority**),**线程默认优先级是5**。Thread类中有三个常量,定义线程优先级范围:

static int MAX_PRIORITY

      线程可以具有的最高优先级。

static int MIN_PRIORITY
线程可以具有的最低优先级。
static int NORM_PRIORITY
分配给线程的默认优先级

JVM线程调度程序是基于优先级的抢先调度机制。在大多数情况下,当前运行的线程优先级将大于或等于线程池中任何线程的优先级。

JAVA多线程面试题整理及答案相关推荐

  1. Java经典面试题整理及答案详解(八)

    简介: Java经典面试题第八节来啦!本节面试题包含了进程.线程.Object类.虚拟内存等相关内容,希望大家多多练习,早日拿下心仪offer- 了解更多: Java经典面试题整理及答案详解(一) J ...

  2. Java经典面试题整理及答案详解(三)

    简介: 以下是某同学面试时,面试官问到的问题,关于面试题答案可以参考以下内容- 上一篇:Java经典面试题整理及答案详解(二) Java面试真题第三弹接住!相信通过前两节的学习,大家对于Java多少有 ...

  3. 【java】Java经典面试题整理(附答案)

    1.JDK 和 JRE 有什么区别? JDK(Java Development Kit),Java开发工具包 JRE(Java Runtime Environment),Java运行环境 JDK中包含 ...

  4. Java经典面试题整理及答案详解(四)

    简介: Java经典面试题第四弹来啦!本节小编整理了关于Java开发框架常见的面试题,希望大家多多怜惜,一起进步- 1.SpringMVC返回值,使用SpringMVC的时候我看到两种风格的开发,一种 ...

  5. 【持续更新】java多线程面试题整理

    1) 什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序员可以通过它进行多处理器编程,你可以使用多线程对 运算密集型任务提速.比如,如果一个线程完 ...

  6. BATJ都爱问的Java多线程面试题整理

    今天给大家总结一下,面试中出镜率很高的几个多线程面试题,希望对大家学习和面试都能有所帮助.备注:文中的代码自己实现一遍的话效果会更佳哦! 一.面试中关于 synchronized 关键字的 5 连击 ...

  7. Java经典面试题整理及答案详解(五)

    Java经典面试题第五弹来啦!本节面试题主要是针对Java初级基础提问,看看你还记得多少? 1.String str="hello",这个字符串对象在栈内存中明明有一个引用(str ...

  8. Java经典面试题整理及答案详解(二)

    简介: 现在找工作,背面试题是一方面,但更重要的就是得把这些代码的前后因果关系了解的非常清楚,还是要多写代码多练习. 1. 使用InputStream用什么方法? 答:Read()方法 2. 在JQu ...

  9. java中高级面试题整理

    java中高级面试题整理                  问题                                                                     ...

  10. 史上最全 Java 多线程面试题及答案

    这篇文章主要是对多线程的问题进行总结的,因此罗列了40个多线程的问题. 这些多线程的问题,有些来源于各大网站.有些来源于自己的思考.可能有些问题网上有.可能有些问题对应的答案也有.也可能有些各位网友也 ...

最新文章

  1. (已解决)ImportError attempted relative import with no known parent package
  2. jQuery 2.0.3 源码分析 Deferred(最细的实现剖析,带图)
  3. Linux 设置端口转发
  4. Swift游戏实战-跑酷熊猫 00 游戏预览
  5. Python-函数和代码复用
  6. C Primer Plus(第六版):C语言概述
  7. asp.net core 错误定位 vs2017 远程调试部署在centos上的asp.net core程序
  8. scm maven_在运行时访问工件的Maven和SCM版本
  9. 在output 子句和 scope_identity() 混合使用的时候的注意事项
  10. cacheable 表达式_Spring缓存注解@Cacheable、@CacheEvict、@CachePut使用
  11. Java 8新特性探究(五)重复注解(repeating annotations)
  12. windows如何根据句柄hwnd显示和隐藏窗口
  13. 如何按照滑环的原理来自制简易导电滑环
  14. mysql多进程模块型_mysql mysqld_multi 单机多进程
  15. 微信小程序云函数服务器,微信小程序云函数使用的几点说明
  16. 论机器学习中数据的重要性
  17. nginx 部署前端项目,不缓存html文件,项目发版后,不用手动刷新页面
  18. 如何将高效设计应用于 DAO?
  19. 报错:NoSuchAlgorithmException: Algorithm HmacSHA1 not available
  20. React学习的小总结

热门文章

  1. 全国计算机二级C语言考试难不难?应该怎么备考?
  2. selenium安装和下载
  3. 开放世界游戏中的大地图背后有哪些实现技术
  4. ENSP-----华为USG6000防火墙
  5. 服务器装系统不识别硬盘分区,安装系统无法识别分区解决方法
  6. 如何选择jquery版本
  7. 2019-CS224n-Assignment2
  8. SLAM和SFM有什么区别?
  9. TextCNN文本分类实践
  10. FTP服务器搭建详细步骤