网站建设的策划文案,2023小规模超过30万怎么交税呢,wordpress投稿管理,私人订制app在典型的 Java 面试中#xff0c; 面试官会从线程的基本概念问起#xff0c; 如#xff1a;为什么你需要使用线程#xff0c;如何创建线程#xff0c;用什么方式创建线程比较好#xff08;比如#xff1a;继承 thread 类还是调用 Runnable 接口#xff09;#xff0c;… 在典型的 Java 面试中 面试官会从线程的基本概念问起 如为什么你需要使用线程如何创建线程用什么方式创建线程比较好比如继承 thread 类还是调用 Runnable 接口然后逐渐问到并发问题像在 Java 并发编程的过程中遇到了什么挑战Java 内存模型JDK1.5 引入了哪些更高阶的并发工具并发编程常用的设计模式经典多线程问题如生产者消费者哲学家就餐读写器或者简单的有界缓冲区问题。 仅仅知道线程的基本概念是远远不够的 必须知道如何处理死锁竞态条件内存冲突和线程安全等并发问 题。 掌握了这些技巧就可以轻松应对多线程和并发面试了。 本篇 Java面试题-线程一 第二篇请戳 Java面试题-线程二 第三篇请戳 Java面试题-线程三 线程1/31 什么是线程2. 线程和进程有什么区别3. 如何在 Java 中实现线程4 用 Runnable 还是 Thread5 Thread 类中的 start () 和 run () 方法有什么区别6 Java 中 Runnable 和 Callable 有什么不同7 Java 中 CyclicBarrier 和 CountDownLatch 有什么不同8 Java 内存模型是什么9 Java 中的 volatile 变量是什么10 什么是线程安全Vector 是一个线程安全类吗11 Java 中什么是竞态条件12 Java 中如何停止一个线程13 一个线程运行时发生异常会怎样14 如何在两个线程间共享数据15 Java 中 notify 和 notifyAll 有什么区别16 为什么 wait, notify 和 notifyAll 这些方法不在 thread 类里面17 什么是 ThreadLocal 变量18 什么是 FutureTask19 Java 中 interrupted 和 isInterruptedd 方法的区别20 为什么 wait 和 notify 方法要在同步块中调用1 什么是线程
线程是操作系统能够进行运算调度的最小单位它被包含在进程之中是进程中的实际运作单位。程序员可以通过它进行多处理器编程你可以使用多线程对运算密集型任务提速。
比如如果一个线程完成一个任务要 100 毫秒那么用十个线程完成改任务只需 10 毫秒。
Java 在语言层面对多线程提供了卓越的支持它也是一个很好的卖点。
2. 线程和进程有什么区别
线程是进程的子集一个进程可以有很多线程每条线程并行执行不同的任务。不同的进程使用不同的内存空间而所有的线程共享一片相同的内存空间。别把它和栈内存搞混每个线程都拥有单独的栈内存用来存储本地数据。
3. 如何在 Java 中实现线程
在语言层面有两种方式。java.lang.Thread 类的实例就是一个线程但是它需要调用java.lang.Runnable 接口来执行由于线程类本身就是调用的 Runnable 接口,所以你可以继承 java.lang.Thread 类或者直接调用 Runnable 接口来重写 run ()方法实现线程。
4 用 Runnable 还是 Thread
这个问题是上题的后续大家都知道我们可以通过继承 Thread 类或者调用 Runnable 接口来实现线程问题是那个方法更好呢什么情况下使用它这个问题很容易回答如果你知道 Java 不支持类的多重继承但允许你调用多个接口。所以如果你要继承其他类当然是调用 Runnable 接口好了。
5 Thread 类中的 start () 和 run () 方法有什么区别
这个问题经常被问到但还是能从此区分出面试者对 Java 线程模型的理解程度。start ()
方法被用来启动新创建的线程而且 start ()内部调用了 run ()方法这和直接调用 run ()
方法的效果不一样。当你调用 run ()方法的时候只会是在原来的线程中调用没有新的
线程启动start ()方法才会启动新线程。
6 Java 中 Runnable 和 Callable 有什么不同
Runnable 和 Callable 都代表那些要在不同的线程中执行的任务。Runnable 从 JDK1.0
开始就有了Callable 是在 JDK1.5 增加的。它们的主要区别是 Callable 的 call () 方法可
以返回值和抛出异常而 Runnable 的 run ()方法没有这些功能。Callable 可以返回装载
有计算结果的 Future 对象。
7 Java 中 CyclicBarrier 和 CountDownLatch 有什么不同
CyclicBarrier 和 CountDownLatch 都可以用来让一组线程等待其它线程。与
CyclicBarrier 不同的是CountdownLatch 不能重新使用。
8 Java 内存模型是什么
Java 内存模型规定和指引 Java 程序在不同的内存架构、CPU 和操作系统间有确定性地行为。它在多线程的情况下尤其重要。Java 内存模型对一个线程所做的变动能被其它线程可 见提供了保证它们之间是先行发生关系。这个关系定义了一些规则让程序员在并发编程时思路更清晰。比如先行发生关系确保了 线程内的代码能够按先后顺序执行这被称为程序次序规则。 对于同一个锁一个解锁操作一定要发生在时间上后发生的另一个锁定操作之前也叫做管程锁定规则。 前一个对 Volatile 的写操作在后一个 volatile 的读操作之前也叫 volatile 变量规则。 一个线程内的任何操作必需在这个线程的 start ()调用之后也叫作线程启动规则。 一个线程的所有操作都会在线程终止之前线程终止规则。 一个对象的终结操作必需在这个对象构造完成之后也叫对象终结规则。 可传递性强烈建议大家阅读《Java 并发编程实践》第十六章来加深对 Java 内存模型的理解。
9 Java 中的 volatile 变量是什么
volatile 是一个特殊的修饰符只有成员变量才能使用它。在 Java 并发程序缺少同步类的情况下多线程对成员变量的操作对其它线程是透明的。volatile 变量可以保证下一个读取操作会在前一个写操作之后发生就是上一题的 volatile 变量规则。点击这里查看更多volatile 的相关内容。
10 什么是线程安全Vector 是一个线程安全类吗
如果你的代码所在的进程中有多个线程在同时运行而这些线程可能会同时运行这段代码。 如果每次运行结果和单线程运行的结果是一样的而且其他的变量的值也和预期的是一样的就是线程安全的。一个线程安全的计数器类的同一个实例对象在被多个线程使用的情况下也不会出现计算失误。很显然你可以将集合类分成两组线程安全和非线程安全的。Vector 是用同步方法来实现线程安全的 而和它相似的 ArrayList 不是线程安全的。
11 Java 中什么是竞态条件
举个例子说明。
竞态条件会导致程序在并发情况下出现一些 bugs。多线程对一些资源的竞争的时候就会产生竞态条件如果首先要执行的程序竞争失败排到后面执行了那么整个程序就会出现一些不确定的 bugs。这种 bugs 很难发现而且会重复出现因为线程间的随机竞争。一个例子就是无序处理。
12 Java 中如何停止一个线程
Java 提供了很丰富的 API 但没有为停止线程提供 API。JDK 1.0 本来有一些像 stop ()suspend () 和 resume ()的控制方法但是由于潜在的死锁威胁因此在后续的 JDK 版本中他们被弃用了之后 Java API 的设计者就没有提供一个兼容且线程安全的方法来停止一个线程。当 run () 或者 call () 方法执行完的时候线程会自动结束如果要手动结束一个线程你可以用 volatile 布尔变量来退出 run ()方法的循环或者是取消任务来中断线程。
13 一个线程运行时发生异常会怎样
这是我在一次面试中遇到的一个很刁钻的 Java 面试题, 简单的说如果异常没有被捕获该线程将会停止执行。Thread.UncaughtExceptionHandler 是用于处理未捕获异常造成线程突然中断情况的一个内嵌接口。当一个未捕获异常将造成线程中断的时候 JVM 会使用Thread.getUncaughtExceptionHandler ()来查询线程的 UncaughtExceptionHandler 并将线程和异常作为参数传递给 handler 的 uncaughtException ()方法进行处理。
14 如何在两个线程间共享数据
可以通过共享对象来实现这个目的或者是使用像阻塞队列这样并发的数据结构。在两个线程间共享对象)用 wait 和 notify 方法实现生产者消费者模型。
15 Java 中 notify 和 notifyAll 有什么区别
这又是一个刁钻的问题因为多线程可以等待单监控锁Java API 的设计人员提供了一些方法当等待条件改变的时候通知它们但是这些方法没有完全实现。notify ()方法不能唤醒某个具体的线程所以只有一个线程在等待的时候它才有用武之地。而 notifyAll ()唤醒所有线程并允许他们争夺锁确保了至少有一个线程能继续运行。
16 为什么 wait, notify 和 notifyAll 这些方法不在 thread 类里面
这是个设计相关的问题它考察的是面试者对现有系统和一些普遍存在但看起来不合理的事物的看法。回答这些问题的时候你要说明为什么把这些方法放在 Object 类里是有意义的还有不把它放在 Thread 类里的原因。一个很明显的原因是 JAVA 提供的锁是对象级的而不是线程级的每个对象都有锁通过线程获得。如果线程需要等待某些锁那么调用对象中的 wait ()方法就有意义了。如果 wait ()方法定义在 Thread 类中线程正在等待的是哪个锁就不明显了。简单的说由于 waitnotify 和 notifyAll 都是锁级别的操作所以把他们定义在 Object 类中因为锁属于对象。
17 什么是 ThreadLocal 变量
ThreadLocal 是 Java 里一种特殊的变量。每个线程都有一个 ThreadLocal 就是每个线程都拥有了自己独立的一个变量竞争条件被彻底消除了。它是为创建代价高昂的对象获取线程安全的好方法比如可以用 ThreadLocal 让 SimpleDateFormat 变成线程安全的因为那个类创建代价高昂且每次调用都需要创建不同的实例所以不值得在局部范围使用它如果为每个线程提供一个自己独有的变量拷贝将大大提高效率。首先通过复用减少了代价高昂的对象的创建个数。其次你在没有使用高代价的同步或者不变性的情况下获得了线程安全。线程局部变量的另一个不错的例子是 ThreadLocalRandom 类它在多线程环境中减少了创建代价高昂的 Random 对象的个数。
18 什么是 FutureTask
在 Java 并发程序中 FutureTask 表示一个可以取消的异步运算。它有启动和取消运算、查询运算是否完成和取回运算结果等方法。只有当运算完成的时候结果才能取回如果运算尚未完成 get 方法将会阻塞。一个 FutureTask 对象可以对调用了 Callable 和 Runnable 的对象进行包装由于 FutureTask 也是调用了 Runnable 接口所以它可以提交给 Executor 来执行。
19 Java 中 interrupted 和 isInterruptedd 方法的区别
interrupted () 和 isInterrupted ()的主要区别是前者会将中断状态清除而后者不会。Java 多线程的中断机制是用内部标识来实现的调用 Thread.interrupt ()来中断一个线程就会设置中断标识为 true。当中断线程调用静态方法 Thread.interrupted ()来检查中断状态时中断状态会被清零。而非静态方法 isInterrupted ()用来查询其它线程的中断状态且不会改变中断状态标识。简单的说就是任何抛出 InterruptedException 异常的方法都会将中断状态清零。无论如何一个线程的中断状态有有可能被其它线程调用中断来改变。
20 为什么 wait 和 notify 方法要在同步块中调用
主要是因为 Java API 强制要求这样做如果你不这么做你的代码会抛出IllegalMonitorStateException 异常。还有一个原因是为了避免 wait 和 notify 之间产生竞态条件。