Q:什么是线程?什么是进程?线程和进程有什么区别?
A:线程:又称"轻量级进程",是操作系统能够进行运算调度的最小单位,被包含在进程之中,是进程中的实际运作单位。
进程: 系统进行资源分配和调度的基本单位。
两者之间的区别:
地址空间和其他资源:进程间相互独立,同一进程的各线程间共享,某进程中的线程在其他进程不可见。
通信:进程间通信 IPC,线程间可以直接读写进程数据段(如全局变量)来进行通信——需要进程同步和互斥手段的辅助,以保证数据的一致性。
调度和切换:线程上下文切换比进程上下文切换要快得多。
在多线程 OS 中,进程不是一个可执行的实体。
Q:多线程编程的好处是什么?
A:发挥多核 CPU 的优势(提高性能)、防止阻塞、便于建模。
Q:有几种创建线程的方式?哪种比较好?
A:①、实现 Runnable 接口(较好:灵活,减少耦合度);②、继承 Thread 类。
Q:Runnable 接口和 Callable 接口的区别?
A:Callable 接口中的 call() 方法是可以返回值和抛出异常,是一个泛型,和 Future / FutureTask 配合来获取结果。而 Runnalbe 接口的 run() 方法,无返回值。
Q:Java 中 CyclicBarrier 和 CountDownLatch 有什么不同?
A:①、CyclicBarrier 是 n 个线程,相互等待;CountDownLatch 是一个或多个线程,等待另外 n 个线程执行完,再执行。
②、CyclicBarrier 加计数;CountDownLatch 减计数。
③、CyclicBarrier 计数达到指定值时,计数置为 0 重新开始;CountDownLatch 计数为 0 时,无法重置。(不可重复利用)
④、CyclicBarrier 调用 await() 方法计数加 1 , 若加 1 后的值不等于构造方法的值,则线程阻塞;CountDownLatch 调用 countDown() 方法计数减 1 ,调用 await() 方法只进行阻塞,对计数没任何影响。
Q:volatile 是什么?作用是什么?
A:volatile 是一个类型修饰符,是用来修饰被不同线程访问和修改的变量。
主要作用有两个:①、内存可见性,即线程 A 对 volatile 变量的修改,其他线程获取的 volatile 变量都是最新的;②、可以禁止指令(程序执行的顺序)重排序。
Q:什么是线程安全?
A:线程安全:多线程访问时,采用了加锁机制,当一个数据访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。
线程不安全:不提供数据访问保护,有可能多个线程先后更改数据造成所得到的数据是脏数据。
Q:线程安全分为哪几种级别?
A:①、不可变:不变的对象绝对是线程安全的,不需要线程同步,如 String、Long、BigInteger;
②、无条件的线程安全:对象自身做了足够多的内部同步,也不需要外部同步,如 Random、ConcurrentHahsMap、Concurrent 集合、atomic;
③、有条件的线程安全:对象的部分方法可以无条件安全使用,但是有些地方需要外部同步,需要 Collectiongs.synchronized;有条件线程安全的最常见的例子是遍历由 HashTable 或者 Vector 或者返回的迭代器;
④、非线程安全(线程兼容):对象本身不提供线程安全机制,但是通过外部同步,可以在并发环境使用,如 ArrayList、HashMap;
⑤、线程对立:即使外部进行了同步调用,也不能保证线程安全,这种情况非常少,如 System.setOut()、System.runFinalizersOnExit()。
Q:如何正确地停止一个线程?
A:①、使用退出标志,使线程正常退出,也就是当 run 方法完成后线程终止;
②、使用 interrupt 方法中断线程;
③、使用 stop 方法强行终止,但是不推荐使用,因为 stop 和 suspend 以及 resume 一样存在死锁威胁,并且都是过期作废的方法。
Q:一个线程运行时发生异常会怎样?
A:①、如果异常没有被捕获,该线程将会停止执行。
②、如果这个线程持有某个对象的监视器,那么这个对象监视器会被立即释放。
Q:两个线程之间,如何实现数据共享?
A:①、使用同一个 Runnable 对象;
②、使用不同的 Runnable 对象:
i、将共享数据分别传递给两个不同的线程;
ii、将这些 Runnable 对象作为一个内部类,将共享数据作为成员变量。
Q:sleep() 方法和 wait() 方法有什么区别?
A:①、所在的类:sleep 在 Thread 类中、wait 在 Object 类中;
②、锁:sleep 方法没有释放锁、wait 方法释放了锁;
③、使用范围:sleep 可以在任何地方使用、而 wait,notify 和 notifyAll 只能在同步控制方法或者同步控制块里面使用。
Q:ThreadLoacl 是什么?作用是什么?
A:它是线程局部变量,每个线程都有自己的 ThreadLocal。
作用:把数据进行隔离,数据不共享(空间换时间,在 Thread 中维护了一个以开地址法实现的 ThreadLocalMap )。
Q:为什么 wait() 方法和 notify()/notifyAll() 方法要在同步块( synchronized )中被调用?
A:JDK 强制的,方法调用之前必须先获得对象的锁。如果不这样做,就会抛出 IllegalMonitorStateException 异常。
Q:同步集合 & 并发集合的区别?
A:都支持线程安全,主要区别体现在性能和可扩展性。
性能:同步集合会把整个 Map 或者 List 锁起来,而并发集合不会。所以同步集合比并发集合慢的多。
可扩展性:并发集合不仅提供线程安全,还用锁分离和内部分区等现代技术来提高可扩展性。
Q:什么是线程池? 为什么要使用它?
A:在程序启动时,就创建若干个线程来响应请求。使用它,可以避免频繁地创建和销毁线程,达到线程对象的重用,还可以根据项目灵活地控制并发的数目。
Q:什么是死锁?死锁发生的必要条件?如何避免死锁?
A:死锁:两个及以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,他们都将无法推进下去。
死锁的必要条件:
①、互斥条件:一个资源每次只能被一个进程使用;
②、请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不变;
③、不剥夺条件:进程已获得的资源,在未使用之前,不能强行剥夺;
④、循环等待条件:若干进程之间形成一种头尾相连的循环等待资源关系。避免死锁最简单的方法:阻止循环等待条件,将系统中所有的资源设置标志位、排序,规定所有的进程申请资源必须以一定的顺序做操作。
Q:活锁 & 死锁的区别?
A:活锁进程的状态可以改变但是却不能继续执行。
Q:怎么检测一个线程是否拥有锁?
A:Thread 中的 holdsLock() 方法:如果当且仅当当前线程拥有某个具体对象的锁时,返回 true。
Q:synchronized & ReentrantLock 的区别?
A:两者都是加锁方式同步(阻塞式同步)。
其本质上的区别:synchronized 是关键字,ReentrantLock 是类。
相对于 synchronized 而言,ReentrantLock 类提供了一些高级功能:
①、等待可中断:持有锁的线程长期不释放时,正在等待的线程可以选择放弃等待,这相等于 synchronized 来说,避免了死锁;
②、公平锁:synchronized 只能是非公平锁,ReenTrantLock 可以通过构造函数的参数来指定公平锁和非公平锁。(公平锁:先等待的线程先得到锁);
③、锁绑定多个条件:一个 ReentrantLock 对象可以同时绑定多个对象。
④、锁机制不一样:synchronized
Q:如何保证线程按照指定顺序执行?
A:使用 new Thread().join() 方法:等待线程结束。也就是说通过一个线程等待另一个线程执行完毕,再继续执行,来实现。
Q:如果你提交任务时,线程池队列已满。会时发会生什么?
A:当一个任务不能被调度执行时,ThreadPoolExecutor 的 submit() 方法将会抛出 RejectedExecutionException 异常。
Q:Java 线程池中 submit() & execute() 方法有什么区别?
A:①、接收的参数不一样;②、submit() 有返回值,execute() 没有
;③、submit() 方便 Exception 处理。
Q:ReadWriteLock 是什么?
A:维护一对关联的锁,一个用于只读操作,一个用于写操作。读锁是共享的,而写锁是独占的。
Q:多线程中的忙循环是什么?使用它的目的是什么?
A:忙循环:用循环让一个线程等待,不会放弃 CPU。
目的:为了保留 CPU 缓存,避免重建缓存和减少等待重建时间。在多核系统中,一个等待线程醒来时,可能会在另一个内核运行,这样就会重建缓存。
Q:遵循的多线程的最佳实践有哪几条?
A:①、给线程起一个有意义的名字;②、避免锁定和缩小同步的范围;③、多用同步类,少用 wait 和 notify;④、多用并发集合,少用同步集合。
Q:如何强制启动一个线程?
A:它是被线程调度器控制的,并且 Java 没有公布相关的 API。
Q:fork-join 框架是什么?
A:Java7 提供了的一个用于并行执行任务的框架, 是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架。使用了工作窃取算法。
网友评论