多线程(相关面试题)

1.多线程有什么用?

1).发挥多核CPU的优势。单核CPU上所谓的"多线程"是假的多线程,同一时间处理器只会处理一段逻辑,只不过线程之间切换得比较快,看着像多个线程"同时"运行。多核CPU上的多线程才是真正的多线程,它能让多段逻辑同时工作。

2)防止阻塞

3)便于建模

2.创建多线程的方式?

1)继承Thread类

2)实现Runnable接口

因为Java只支持单继承,而接口可以多实现。

3)实现Callable接口

通过实现Callable接口并重写call方法,并把Callable实例传给FutureTask对象,再把FutureTask对象传给Thread对象

3.start()方法和run()方法的区别?

启动一个线程是调用start()方法,run()方法可以产生必须退出的标志来停止一个线程。

只有调用了start()方法,才会表现出多线程的特性,不同线程的run()方法里面的代码交替执行。如果只是调用了

run()方法,那么代码还是同步执行的,必须等待一个线程的run()方法里面的代码全部执行完,另一个线程才可以执行

其run()方法里面的代码。

4.Runnable接口和Callable接口的区别?

Runnable接口中的run()方法的返回值是void,它做的事情只是纯粹地去执行run()方法中的代码而已;Callable接口

中的call()方法是有返回值的,是一个泛型,和Futrue、FutrueTask配合可以用来获取异步的结果。

特性:多线程相比单线程更难、更复杂的一个重要原因就是多线程充满着未知性

5.CyclicBarrier和CountDownLatch的区别?

都是java.util.concurrent下。

1)CyclicBarrier的某个线程运行到某个点上之后,该线程即停止运行,直到所有的线程都达到这个点,所有线程才重新运行。

  CountDownLatch则不是,某线程运行到某个点上之后,只是给某个数值-1而已,该线程继续运行。

2)CyclicBarrier只能唤起一个任务,CountDownLatch可以唤起多个任务。

3)CyclicBarrier可重用,CountDownLatch不可重用,计数值为0该CountDownLatch就不可再用。

6.volatile关键字作用?(不懂)

1)多线程主要围绕可见性和原子性两个特性而展开,使用volatile关键字修饰的变量,保证了其在多线程之间的可见性,即每次读到volatile变量,一定是最新的数据。

2)和CAS结合,保证了原子性。

使用volatile关键字:1.对变量的写操作不依赖当前变量的值   2.该变量没有包含在其他变量的不变式中。

7.什么是线程安全?

1)不可变

像String、Integer、Long 这些都是final类型的类,任何一个线程都改变不了他们的值

2)绝对线程安全

不管运行时环境如何,调用者都不需要额外的同步措施。

3)相对线程安全

像Vector这种,add、remove方法都是原子操作,不会被打断,也就是fail_fast机制(不懂)

8.Java中如何获取到线程dump文件(不懂)

死循环、死锁、阻塞、页面打开快慢等问题,线程dump是最好解决问题的路径。所谓的dump也就是线程堆栈,获取到线程堆栈

有两步:

1)获取线程的pid,可以通过使用jps命令,在Linux环境下还可以使用ps -ef |  grep  java

2)打印线程堆栈,可以通过使用jstack  pid 命令,在Linux环境下还可以使用 kill  -3 pid

另外,Thread类提供了一个getStackTrace()方法也可以获取线程堆栈。

9.一个线程如果出现了运行时异常会怎么样?

如果这个异常没有被捕获的话,这个线程就停止执行了。另外重要的一点:如果这个线程持有某个对象的监视器,那么这个对象监视器会被立即释放。

10.如何在两个线程之间共享数据?

通过在线程之间共享对象就Ok,然后通过wait/notify/notifyAll      await/singal/singalAll进行唤起和等待,比方说阻塞队列

BlockingQueue就是为了线程之间共享数据而设计的。

11.sleep方法和wait方法有什么区别?

1)sleep来自Thead类,wait来自Object类

2)sleep方法没有释放锁,而wait方法释放了锁。

3)如果线程持有某个对象的监视器,sleep方法不会放弃这个对象的监视器,wait方法会放弃这个对象的监视器(不懂)

12.生产者消费者模型的作用是什么?(不懂)

1)通过平衡生产者的生产能力和消费者的消费能来提升整个系统的运行效率,这是生产者消费者模型最重要的作用。

2)解耦,这是生产者模型附带的作用,解耦意味着生产者和消费者之间的联系少,联系越少越可以独自发展而不需要收到相互的制约

13.ThreadLocal有什么用?(不懂)

简单说ThreadLocal就是一种以空间换时间的做法,把数据进行隔离,数据不共享,自然没有线程安全方面的问题了。

14.为什么wait()方法和notify()/nofityAll()方法要在同步快中被调用?

这是JDK强制的,wait()方法和notify()/notifyAll()方法在调用前都必须先获取对象的锁。

15.wait()方法和notify()/notifyAll()方法在放弃对象监视器时有什么区别?

wait()方法和notify()/notifyAll()方法在放弃对象监视器的时候区别在于:wait()方法立即释放对象监视器,notify()/notifyAll()方法则会等待线程剩余的代码执行完毕才会放弃对象监视器。

16.为什么使用线程池?

避免频繁地创建和销毁线程,达到线程对象的重用。

17.怎么检测一个线程是否持有对象监视器?(不懂)

Thread类提供了一个holdsLock(Object   obj)方法,当且仅当对象obj的监视器被某条线程的持有的时候才会返回true,注意这是一个static方法,这意味着"某条线程"指的是当前线程。

18.synchronized和ReentrantLock的区别?(不懂)

synchronized是和if、else、for、while一样的关键字,ReentrantLock是类,这是二者的本质区别。

1)ReentrantLock可以对获取锁的等待时间进行设置,这样就避免了死锁。

2)ReentrantLock可以获取各种锁的信息

3)ReentrantLock可以灵活地实现多路通知,另外,二者的锁机制其实也是不一样的。

19.ConcurrentHashMap的并发度是什么?

ConcurrentHashMap的并发度就是segment的大小,默认为16,这意味着最多同时可以有16 条线程操作ConcurrentHashMap,这也是ConcurrentHashMap对HashTable的最大优势。

20.ReadWriteLock是什么?

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

21.FutureTask是什么?(不懂)

FutureTask表示一个异步运算的任务,FutureTask里面可以传一个Callable的具体实现类。

22.Linux环境下如何查找哪个线程使用CPU最长?

1)获取项目的pid,jps或者ps -ef | grep java,

2)top -H  -p  pid ,顺序不能改变。(打印当前的项目,每条线程占用CPU时间的百分比。)

23.Java编程写一个会导致死锁的程序?

1)两个线程里面分别持有两个Object对象:lock1和lock2.这两个lock作为同步代码块的锁。

2)线程1的run()方法中同步代码先获取lock1的对象锁,Thread.sleep(xxx),然后接着获取lock2的对象锁。

3)线程2的run()方法中同步代码块先获取lock2的对象锁,接着获取lock1的对象锁

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值