什么是守护线程?有什么用?

守护线程相对应的就是用户线程,守护线程就是守护用户线 程,当用户线程全部执行完结束之后,守护线程才会跟着结束。也就是守护线程必 须伴随着用户线程,如果一个应用内只存在一个守护线程,没有用户线程,守护线 程自然会退出

一个线程运行时发生异常会怎样?

如果异常没有被捕获该线程将会停止执行。Thread.UncaughtExceptionHandler 是用 于处理未捕获异常造成线程突然中断情况的一个内嵌接口。当一个未捕获异常将造 成线程中断的时 候 JVM 会 使 用 Thread.getUncaughtExceptionHandler() 来 查 询 线 程 的UncaughtExceptionHandler 并 将 线 程 和 异 常 作 为 参 数 传 递 给 handler 的 uncaughtException()方法进行处理。

线程 yield()方法有什么用?

yield 方法可以暂停当前正在执行的线程对象,让其它有相同优先级的线程执行。 它是一个静态方法而且只保证当前线程放弃 CPU 占用而不能保证使其它线程一定 能占用 CPU,执行yield()的线程有可能在进入到暂停状态后马上又被执行。

什么是重入锁?

所谓重入锁,指的是以线程为单位,当一个线程获取对象锁之后,这个线程可以再 次获取本对象上的锁,而其他的线程是不可以的。

Synchronized 有哪几种用法?

锁类、锁方法、锁代码块。

Fork/Join 框架是干什么的?

大任务自动分散小任务,并发执行,合并小任务结果。

线程数过多会造成什么异常?

线程过多会造成栈溢出,也有可能会造成堆异常

说说HashMap线程安全的和不安全的产生场景。

Java 中平时用的最多的 Map 集合就是 HashMap 了,它是线程不安全的。

看下面两个场景:

1、当用在方法内的局部变量时,局部变量属于当前线程级别的变量,其他线程访 问不了,所以这时也不存在线程安全不安全的问题了。

2、当用在单例对象成员变量的时候呢?这时候多个线程过来访问的就是同一个 HashMap 了,对同个 HashMap 操作这时候就存在线程安全的问题了。

什么是 CAS 算法?在多线程中有哪些应用

CAS,全称为 Compare and Swap,即比较-替换。假设有三个操作数:内存值 V、 旧的预期值 A、要修改的值 B,当且仅当预期值 A 和内存值 V 相同时,才会将内 存值修改为 B 并返回 true,否则什么都不做并返回 false。当然 CAS 一定要 volatile 变量配合,这样才能保证每次拿到的变量是主内存中最新的那个值,否则旧的预期 值 A 对某条线程来说,永远是一个不会变的值 A,只要某次 CAS 操作失败,永远 都不可能成功。 java.util.concurrent.atomic 包下面的 Atom类都有 CAS 算法的应用。

怎么检测一个线程是否拥有锁?

java.lang.Thread#holdsLock 方法

Jdk 中排查多线程问题用什么命令?

jstack

线程同步需要注意什么?

1、尽量缩小同步的范围,增加系统吞吐量。

2、分布式同步锁无意义,要使用分布式锁。

3、防止死锁,注意加锁顺序。

线程 wait()方法使用有什么前提?

要在同步块中使用

Fork/Join 框架使用有哪些要注意的地方?

如果任务拆解的很深,系统内的线程数量堆积,导致系统性能性能严重下降; 如果函数的调用栈很深,会导致栈内存溢出;

线程之间如何传递数据?

通 过 在 线 程 之 间 共 享 对 象 就 可 以 了守护线程, 然 后 通 过 wait/notify/notifyAll 、 await/signal/signalAll 进行唤起和等待,比方说阻塞队列 BlockingQueue 就是为线程 之间共享数据而设计的

保证”可见性”有哪几种方式?

synchronized 和 viotatile

说几个常用的 Lock 接口实现锁?

ReentrantLock、ReadWriteLock

ReadWriteLock 有什么用?

ReadWriteLock 是一个读写锁接口,ReentrantReadWriteLock 是 ReadWriteLock 接 口的一个具体实现,实现了读写的分离,读锁是共享的,写锁是独占的,读和读之间不会互斥,读和写、写和读、写和写之间才会互斥,提升了读写的性能

ThreadLocal 是什么?有什么应用场景?

ThreadLocal 的作用是提供线程内的局部变量,这种变量在线程的生命周期内起作 用,减少同一个线程内多个函数或者组件之间一些公共变量的传递的复杂度。用来 解决数据库连接、Session 管理等

FutureTask 是什么?

FutureTask 表示一个异步运算的任务,FutureTask 里面可以传入一个 Callable 的具 17 体实现类,可以对这个异步运算的任务的结果进行等待获取、判断是否已经完成、 取消任务等操作

怎么唤醒一个阻塞的线程?

如果线程是因为调用了 wait()、sleep()或者 join()方法而导致的阻塞,可以中断线程, 并且通过抛出 InterruptedException 来唤醒它;如果线程遇到了 IO 阻塞,无能为力, 因为 IO是操作系统实现的,Java 代码并没有办法直接接触到操作系统

不可变对象对多线程有什么帮助?

不可变对象保证了对象的内存可见性,对不可变对象的读取不需要进行额外的同步 手段,提升了代码执行效率。

多线程上下文切换是什么意思?

多线程的上下文切换是指 CPU 控制权由一个已经正在运行的线程切换到另外一个 就绪并等待获取 CPU 执行权的线程的过程。

Java 中用到了什么线程调度算法?

抢占式。一个线程用完 CPU 之后,操作系统会根据线程优先级、线程饥饿情况等 数据算出一个总的优先级并分配下一个时间片给某个线程执行。

Thread.sleep(0)的作用是什么?

由于 Java 采用抢占式的线程调度算法,因此可能会出现某条线程常常获取到 CPU 控制权的情况,为了让某些优先级比较低的线程也能获取到 CPU 控制权,可以使 用 Thread.sleep(0)手动触发一次操作系统分配时间片的操作,这也是平衡 CPU 控制 权的一种操作

什么是乐观锁和悲观锁?

乐观锁:就像它的名字一样,对于并发间操作产生的线程安全问题持乐观状态,乐 观锁认为竞争不总是会发生,因此它不需要持有锁,将比较-替换这两个动作作为 一个原子操作尝试去修改内存中的变量,如果失败则表示发生冲突,那么就应该有 相应的重试逻辑。 悲观锁:还是像它的名字一样,对于并发间操作产生的线程安全问题持悲观状态, 悲观锁认为竞争总是会发生,因此每次对某资源进行操作时,都会持有一个独占的 锁,就像synchronized,不管三七二十一,直接上了锁就操作资源了

Hashtable 的 size()方法为什么要做同步?

同一时间只能有一条线程执行固定类的同步方法,但是对于类的非同步方法,可以 多条线程同时访问。所以,这样就有问题了,可能线程 A 在执行 Hashtable 的 put 方法添加数据,线程 B 则可以正常调用 size()方法读取 Hashtable 中当前元素的个 数,那读取到的值可能不是最新的守护线程,可能线程 A 添加了完了数据,但是没有对 size++,线程 B 就已经读取 size了,那么对于线程 B 来说读取到的 size 一定是不准 确的。而给 size()方法加了同步之后,意味着线程 B 调用 size()方法只有在线程 A 调用 put 方法完毕之后才可以调用,这样就保证了线程安全性CPU 执行代码,执行 的不是 Java 代码,这点很关键,一定得记住。Java 代码最终是被翻译成机器码执 行的,机器码才是真正可以和硬件电路交互的代码。即使你看到 Java 代码只有一 行,甚至你看到 Java 代码编译之后生成的字节码也只有一行,也不意味着对于底 层来说这句语句的操作只有一个。一句”return count”假设被翻译成了三句汇编语句 执行,一句汇编语句和其机器码做对应,完全可能执行完第一句,线程就切换了

同步方法和同步块,哪种更好?

同步块,这意味着同步块之外的代码是异步执行的,这比同步整个方法更提升代码 的效率。 请知道一条原则:同步的范围越小越好。

什么是自旋锁?

自旋锁是采用让当前线程不停地的在循环体内执行实现的,当循环的条件被其他线 程改变时才能进入临界区

Runnable 和 Thread 用哪个好?

Java 不支持类的多重继承,但允许你实现多个接口。所以如果你要继承其他类,也 19 为了减少类之间的耦合性,Runnable 会更好。

Java 中 notify 和 notifyAll 有什么区别?

notify()方法不能唤醒某个具体的线程,所以只有一个线程在等待的时候它才有用 武之地。 而 notifyAll()唤醒所有线程并允许他们争夺锁确保了至少有一个线程能继续运行

为什么 wait/notify/notifyAll 这些方法不在 thread 类里面?

这是个设计相关的问题,它考察的是面试者对现有系统和一些普遍存在但看起来不 合理的事物的看法。回答这些问题的时候,你要说明为什么把这些方法放在 Object 类里是有意义的,还有不把它放在 Thread 类里的原因。一个很明显的原因是 JAVA 提供的锁是对象级的而不是线程级的,每个对象都有锁,通过线程获得。如 果线程需要等待某些锁那么调用对象中的wait()方法就有意义了。如果 wait()方法定 义在 Thread 类中,线程正在等待的是哪个锁就不明显了。简单的说,由于 wait, notify 和 notifyAll 都是锁级别的操作,所以把他们定义在 Object 类中因为锁属于对 象。

为什么 wait 和 notify 方法要在同步块中调用?

主 要 是 因 为 Java API 强 制 要 求 这 样 做 , 如 果 你 不 这 么 做 , 你 的 代 码 会 抛 出IllegalMonitorStateException 异常。还有一个原因是为了避免 wait 和 notify 之间产生竞态条件

为什么你应该在循环中检查等待条件?

处于等待状态的线程可能会收到错误警报和伪唤醒,如果不在循环中检查等待条件, 程序就会在没有满足结束条件的情况下退出。因此,当一个等待线程醒来时,不能 认为它原来的等待状态仍然是有效的,在 notify()方法调用之后和等待线程醒来之 前这段时间它可能会改变。这就是在循环中使用 wait()方法效果更好的原因,你可 以在 Eclipse 中创建模板调用 wait和 notify 试一试

Java 线程中堆和栈有什么不同?

每个线程都有自己的栈内存,用于存储本地变量,方法参数和栈调用,一个线程中 存储的变量对其它线程是不可见的。而堆是所有线程共享的一片公用内存区域。对 象都在堆里创建,为了提升效率线程会从堆中弄一个缓存到自己的栈,如果多个线 程使用该变量就可能引发问题,这时 volatile 变量就可以发挥作用了,它要求线程 从主存中读取变量的值

你如何在 Java 中获取线程堆栈?

对于不同的操作系统,有多种方法来获得 Java 进程的线程堆栈。当你获取线程堆 栈时,JVM会把所有线程的状态存到日志文件或者输出到控制台。在 Windows 你 可以使用 Ctrl + Break 组合键来获取线程堆栈,Linux 下用 kill -3 命令。你也可以 用 jstack 这个工具来获取,它对线程 id 进行操作,你可以用 jps 这个工具找到 id

如何创建线程安全的单例模式?

单例模式即一个 JVM 内存中只存在一个类的对象实例分类

1、懒汉式 类加载的时候就创建实例

2、饿汉式 使用的时候才创建实例

什么是阻塞式方法?

阻塞式方法是指程序会一直等待该方法完成期间不做其他事情,ServerSocket 的 110 accept()方法就是一直等待客户端连接。这里的阻塞是指调用结果返回之前,当前 线程会被挂起,直到得到结果之后才会返回。此外,还有异步和非阻塞式方法在任 务完成前就返回。

提交任务时线程池队列已满会时发会生什么?

当线程数小于最大线程池数 maximumPoolSize 时就会创建新线程来处理,而线程 数大于等于最大线程池数 maximumPoolSize 时就会执行拒绝策略

限时特惠:本站每日持续更新海量设计资源,一年会员只需29.9元,全站资源免费下载
站长微信:ziyuanshu688