详情页设计与制作,网站品牌词优化怎么做,网站开发要跑道吗,专做网页的网站Java多线程面试题#xff08;一#xff09; 前言1、在 Java 中守护线程和本地线程区别#xff1f;2、线程与进程的区别#xff1f;3、什么是多线程中的上下文切换#xff1f;4、死锁与活锁的区别#xff0c;死锁与饥饿的区别#xff1f;5、Java 中用到的线程调度算法是什… Java多线程面试题一 前言1、在 Java 中守护线程和本地线程区别2、线程与进程的区别3、什么是多线程中的上下文切换4、死锁与活锁的区别死锁与饥饿的区别5、Java 中用到的线程调度算法是什么6、为什么使用 Executor 框架7、在 Java 中 Executor 和 Executors 的区别8、如何在 Windows 和 Linux 上查找哪个线程使用的 CPU 时间最长9、什么是 Executors 框架10、什么是阻塞队列阻塞队列的实现原理是什么11、什么是 Callable 和 Future12、什么是 FutureTask13、什么是并发容器的实现14、多线程同步和互斥有几种实现方法都是什么15、什么是竞争条件你怎样发现和解决竞争16、你将如何使用 thread dump你将如何分析 Thread dump17、为什么我们调用 start()方法时会执行 run()方法18、Java 中你怎样唤醒一个阻塞的线程19、什么是不可变对象它对写并发应用有什么帮助?20、为什么使用 Executor 线程池框架总结 前言
最新的 Java 面试题技术栈涉及 Java 基础、集合、多线程、Mysql、分布式、Spring全家桶、MyBatis、Dubbo、缓存、消息队列、Linux…等等会持续更新。
如果对老铁有帮助帮忙免费点个赞谢谢你的发财手
1、在 Java 中守护线程和本地线程区别
Java中任何线程都可以设置为守护线程和用户线程通过方法 Thread.setDaemon(true) true 则把该线程设置为守护线程默认false为用户线程 要注意的是Thread.setDaemon() 必须在 Thread.start()之前调用否则运行时会抛出异常。 两者的区别就是判断虚拟机(JVM)何时离开 用户线程就是如果有任何一个用户线程未结束Java虚拟机是不会结束的。 守护线程就是如果只剩守护线程未结束那么Java虚拟机就会结束了。
2、线程与进程的区别
首先定义不一样进程是一个在内存中运行的应用程序而线程是进程中的一个执行任务 一个线程只可以属于一个进程但一个进程能包含多个线程, 多个线程可共享数据。
3、什么是多线程中的上下文切换
是指线程数大于给程序分配的CPU数量时为了让各个线程都有执行的机会就需要切换使用CPU 不同的线程切换使用CPU发生的切换数据等 就是上下文切换。
4、死锁与活锁的区别死锁与饥饿的区别
死锁是指两个或两个以上的进程或线程在执行过程中因争夺资源而造成的一种互相等待的现象若无外力作用它们都将无法推进下去。 产生死锁的必要条件 1、独占资源一个资源每次只能给一个进程使用比如写操作 2、占有且申请进程在申请新的资源的同时保持对原有资源的占有 3、不可夺取资源申请者不能强行从资源占有者手中夺取资源资源只能由占有者自愿释放 4、循环等待线程1等待线程2占有的资源线程2等待线程1占有的资源形成了一个进程等待回路。 典型案例哲学家共进午餐问题活锁任务或者执行者没有被阻塞由于某些条件没有满足导致一直重复尝试失败尝试失败。活锁有可能自行解开死锁则不能。 饥饿是指一个可运行的进程被调度器无限期地忽视而不能被调度执行的情况。
5、Java 中用到的线程调度算法是什么
有两种调度模型分时调度模型和抢占式java默认使用调度模型。
分时调度模型 平均分配每个线程占用的 CPU 的时间片。抢占式调度模型 让优先级高的线程占用CPU如果线程优先级相同那么就随机选择一个线程可以通过 setPriority1~10设置优先级
6、为什么使用 Executor 框架
Executor是一个多线程管理框架创建线程的方式有三种Thread、Runnable、Callable 调用 new Thread()创建的线程缺乏管理被称为野线程而且可以无限制的创建线程之间的相互竞争会导致过多占用系统资源而导致系统瘫痪还有线程之间的频繁交替也会消耗很多系统资源。 接使用 new Thread() 启动的线程不利于扩展比如定时执行、定期执行、定时定期执行、线程中断等都不便实现。
7、在 Java 中 Executor 和 Executors 的区别
Executors 工具类的不同方法按照我们的需求创建了不同的线程池来满足业务的需求。 Executor 接口对象能执行我们的线程任务。 ExecutorService 接口继承了 Executor 接口并进行了扩展提供了更多的方法我们能获得任务执行的状态并且可以获取任务的返回值。 使用 ThreadPoolExecutor 可以创建自定义线程池。 Future 表示异步计算的结果他提供了检查计算是否完成的方法以等待计算的完成并可以使用 get()方法获取计算的结果。
8、如何在 Windows 和 Linux 上查找哪个线程使用的 CPU 时间最长
使用 jstack 找出消耗 CPU 最多的线程代码。
9、什么是 Executors 框架
Executor 框架是一个根据一组执行策略调用调度执行和控制的异步任务的框架。 无限制的创建线程会引起应用程序内存溢出所以创建一个线程池是个更好的的解决方案因为可以限制线程的数量并且可以回收再利用这些线程利用Executors 框架可以非常方便的创建一个线程池。
10、什么是阻塞队列阻塞队列的实现原理是什么
阻塞队列BlockingQueue是一个支持两个附加操作的队列。 这两个附加的操作是在队列为空时获取元素的线程会等待队列变为非空。当队列满时存储元素的线程会等待队列可用。 阻塞队列常用于生产者和消费者的场景生产者是往队列里添加元素的线程消费者是从队列里拿元素的线程。阻塞队列就是生产者存放元素的容器而消费者也只从容器里拿元素
11、什么是 Callable 和 Future
Callable 接口类似于 Runnable从名字就可以看出来了但是 Runnable 不会返回结果并且无法抛出返回结果的异常而 Callable 功能更强大一些被线程执行后可以返回值这个返回值可以被 Future 拿到也就是说Future 可以拿到异步执行任务的返回值。 可以认为是带有回调的 Runnable。 Future 接口表示异步任务是还没有完成的任务给出的未来结果。所以说 Callable 用于产生结果Future 用于获取结果。
12、什么是 FutureTask
在 Java 并发程序中 FutureTask 表示一个可以取消的异步运算。它有启动和取消运算、查询运算是否完成和获取运算结果等方法只有当运算完成的时候结果才能取回如果运算尚未完成 get 方法将会阻塞。当一个线程需要等待另一个线程把某个任务执行完后它才能继续执行此时可以使用FutureTask。
13、什么是并发容器的实现
我们先从并发容器的由来谈起。Java的集合容器框架中主要有四大类别List、Set、Queue、Map我们熟知的这些集合类ArrayList、LinkedList、HashMap这些容器都不是线程安全的如果有多个线程并发地访问这些容器时就会出现问题。因此Java提供了同步容器供用户使用。
同步容器可以简单地理解为通过synchronized来实现同步的容器比如Vector、Hashtable以及SynchronizedList等容器这样做的代价是削弱了并发性当多个线程共同竞争容器级的锁时吞吐量就会降低因此为了解决同步容器的性能问题所以才有了并发容器。并发类容器是专门针对多线程并发设计的采用了CAS算法和部分代码使用synchronized锁保证线程安全只对操作的位置进行同步操作但是其他没有操作的位置其他线程仍然可以访问提高了程序的吞吐量。 java.util.concurrent包中提供了多种并发类容器比如ConcurrentHashMap、CopyOnWriteArrayList CopyOnWriteArraySet等等。 CAS算法它可以不使用锁而保证多线程安全所以CAS也是一种无锁算法也是乐观锁的提现。
14、多线程同步和互斥有几种实现方法都是什么
线程同步是指一个线程的执行依赖另一个线程的消息当它没有得到另一个线程的消息时应等待直到消息到达时才被唤醒。 线程互斥是指当有若干个线程都要使用某一共享资源时任何时刻最多只允许一个线程去使用其它要使用该资源的线程必须等待直到占用资源者释放该资源。线程互斥可以看成是一种特殊的线程同步。 线程间的同步方法大体可分为两类用户模式和内核模式。顾名思义内核模式就是指利用系统内核对象的单一性来进行同步使用时需要切换内核态与用户态而用户模式就是不需要切换到内核态只在用户态完成操作。
15、什么是竞争条件你怎样发现和解决竞争
在java多线程中当两个或以上的线程对同一个数据进行操作的时候可能会产生“竞争条件”的现象。这时候需要加锁来解决多线程操作同一个数据时可能产生的问题。加锁方式有两种一h种是Lock对象来对语句快进行加锁另一种是通过synchronized 关键字来对方法进行加锁。以上两种方法都可以有效解决多线程中存在的竞争条件的问题。
16、你将如何使用 thread dump你将如何分析 Thread dump
Thread Dump是非常有用的诊断Java应用问题的工具 1、可以查找内存泄露2、可以发现死锁线程。 然后分析Thread Dump的各个部分 1、头部信息2、线程类型3、线程优先级4、jvm线程id5、线程状态 注意看这个
初始化状态New 在调用start()方法之前就绪状态Runnable 调用了start()方法该线程就进入就绪状态只有处于就绪状态的线程才能获得CPU的使用权。运行状态Running 线程获得CPU的使用权执行程序代码。阻塞超时状态Blocked 线程因为某些原因放弃 CPU暂时停止运行。比如执行了某个对象的 wait()方法、或者执行了sleep()方法或者调用了其他线程的 join()方法。死亡状态Dead 线程的run()运行结束调用stop()方法或者在运行过程中出现了未捕获的异常时线程进入死亡状态Thread Dump是非常有用的诊断Java应用问题的工具 1、可以查找内存泄露2、可以发现死锁线程。 然后分析Thread Dump的各个部分 头部信息2、线程类型3、线程优先级4、jvm线程id5、线程状态。
17、为什么我们调用 start()方法时会执行 run()方法
在调用start()方法后线程并不能立即开始执行run()方法而是处于就绪状态Runnable等待线程调度程序为其分配CPU时间片并使其进入运行状态Running当线程获得CPU资源后就会自动调用其对应的run()方法开始执行线程代码。 Thread类中的start()方法实际上是一个异步调用它会立即返回并继续执行下一条语句而不会等待线程执行完毕。 但是如果你直接调用 run()方法它不会创建新的线程只会把 run 方法当作普通方法去执行 。
18、Java 中你怎样唤醒一个阻塞的线程
在 Java 中使用 Object 类的 wait()和 notify()方法实现线程阻塞和唤醒。 wait、notify方法是针对对象的而且必须在 synchronized 块或方法中被调用。 调用wait()方法都会导致线程阻塞阻塞的同时也会释放该对象的锁相应地调用notify()方法则将解除该对象阻塞的线程但它需要重新获取该对象的锁直到获取成功才能往下执行。
19、什么是不可变对象它对写并发应用有什么帮助?
不可变对象是指对象一旦被创建它的状态即对象属性值就不能改变。 比如 String、8种基本类型的包装类等。不可变对象永远是线程安全的。
20、为什么使用 Executor 线程池框架
线程池就是为了管理线程的生命周期提高效率优点如下
1、可以复用线程从而减少线程对象的反复创建和销毁。2、可有效控制最大并发线程数提高系统资源使用率。3、框架中还有定时、定期、并发数控制等功能。 综上所述使用线程池框架 Executor 能更好的管理线程、提供系统资源使用率。
总结
都已经看到这里啦赶紧收藏起来祝您工作顺心生活愉快