金三银四跳槽季(四)多线程

1、 wait和sleep的区别

sleep()方法是属于Thread类中的,而wait()方法,则是属于Object类中的。
sleep()方法导致了程序暂停执行指定的时间,让出cpu给其他线程,但是他的监控状态依然保持着,当指定的时间到了又会自动恢复运行状态。所以在调用sleep()方法的过程中,线程不会释放对象锁。
③调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。

2、Volatile和Synchronized四个不同点:

① 粒度不同,前者针对变量 ,后者锁对象和类
syn阻塞,volatile线程不阻塞
syn保证三大特性,volatile不保证原子性
syn编译器优化,volatile不优化 volatile具备两种特性:

1.保证此变量对所有线程的可见性,指一条线程修改了这个变量的值,新值对于其他线程来说是可见的,但并不是多线程安全的。
2.禁止指令重排序优化。

Volatile如何保证内存可见性:

1.当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量刷新到主内存。
2.当读一个volatile变量时,JMM会把该线程对应的本地内存置为无效。线程接下来将从主内存中读取共享变量。

  • 同步:就是一个任务的完成需要依赖另外一个任务,只有等待被依赖的任务完成后,依赖任务才能完成。
  • 异步:不需要等待被依赖的任务完成,只是通知被依赖的任务要完成什么工作,只要自己任务完成了就算完成了,被>依赖的任务是否完成会通知回来。(异步的特点就是通知)。 打电话和发短信来比喻同步和异步操作。
  • 阻塞:CPU停下来等一个慢的操作完成以后,才会接着完成其他的工作。
  • 非阻塞:非阻塞就是在这个慢的执行时,CPU去做其他工作,等这个慢的完成后,CPU才会接着完成后续的操作。
    非阻塞会造成线程切换增加,增加CPU的使用时间能不能补偿系统的切换成本需要考虑。

3、线程池的作用:

在程序启动的时候就创建若干线程来响应处理,它们被称为线程池,里面的线程叫工作线程


  • 第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。

  • 第二:提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。

  • 第三:提高线程的可管理性。

常用线程池:ExecutorService 是主要的实现类,其中常用的有 Executors.newSingleThreadPool(),newFixedThreadPool(),newcachedTheadPool(),newScheduledThreadPool()

4、notify和notifyAll区别

他们的作用都是通知处于等待该对象的线程。

  • notifyAll使所有原来在该对象上等待被notify的线程统统退出wait的状态,变成等待该对象上的锁,一旦该对象被解锁,他们就会去竞争。

  • notify是通知其中一个线程,不会通知所有的线程

2、实现线程有哪几种方式?

有三种方式可以用来创建线程:

  • 继承Thread类
  • 实现Runnable接口
  • 应用程序可以使用Executor框架来创建线程池

实现Runnable接口这种方式更受欢迎,因为这不需要继承Thread类。在应用设计中已经继承了别的对象的情况下,这需要多继承(而Java不支持多继承),只能实现接口。同时,线程池也是非常高效的,很容易实现和使用。

3、线程有哪几种状态?它们之间如何流转的?

4、线程中的start()和run()方法有什么区别?

5、怎么终止一个线程?如何优雅地终止线程?

6、ThreadLocal在多线程中扮演什么角色?

7、线程中的wait()和sleep()方法有什么区别?

8、多线程同步有哪几种方法?

9、什么是死锁?如何避免死锁?

两个进程都在等待对方执行完毕才能继续往下执行的时候就发生了死锁。结果就是两个进程都陷入了无限的等待中。
使用多线程的时候,一种非常简单的避免死锁的方式就是:指定获取锁的顺序,并强制线程按照指定的顺序获取锁。因此,如果所有的线程都是以同样的顺序加锁和释放锁,就不会出现死锁了。

10、多线程之间如何进行通信?

11、线程怎样返回结果?如何获取?

12、说说violatile关键字有什么用,和Synchronized有什么区别?

13、假如新建T1、T2、T3三个线程,如何保证它们按顺序执行?

这个线程问题通常会在第一轮或电话面试阶段被问到,目的是检测你对”join”方法是否熟悉。这个多线程问题比较简单,可以用join方法实现。

14、怎么控制同一时间只有3个线程运行?

15、为什么要使用线程池?

16、说一说常用的几种线程池并讲讲其中的工作原理。

17、线程池启动线程submit()和execute()有什么不同?

18、说说多线程并发控制中的倒计时器、循环栅栏是什么,有什么应用场景?

19、什么是活锁、饥饿、无锁、死锁?

20、什么是原子性、可见性、有序性?

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

22、怎么中断一个线程?如何保证中断业务不影响?

23、yield()方法有什么用?

24、什么是重入锁,和Synchronized锁有什么区别?

25、Synchronized有哪几种用法?

26、Fork/Join框架是干什么的?

27、如何给线程传递参数?

28、说说线程安全的和不安全的集合。

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

30、你遇到过哪些多线程的问题?都是如何解决的

31、volatile如何保证可见性

使用volatile修饰时,可以理解成所有的操作都放到了主存中,,多个线程共享数据时,可以保证内存中的数据可见,一个线程修改了数据,会立即更新到主存,下一个线程使用时一定是最新的数据,这便是可见性

1)说说阻塞队列的实现:可以参考ArrayBlockingQueue的底层实现(锁和同步都行);
2)进程通讯的方式:消息队列,共享内存,信号量,socket通讯等;
3)用过并发包的哪些类;
4)什么地方用了多线程;
5)Excutors可以产生哪些线程池;
6)为什么要用线程池;
7)volatile关键字的用法:使多线程中的变量可见;

猜你喜欢

转载自blog.csdn.net/dreamsunday/article/details/79964257