***:Java多线程面试题1:进程和线程有什么区别?进程是一个独立的(selfcontained)运行环境,它可以看作是一个程序或一个应用程序。线程是在进程中执行的任务。Java运行时是包含不同类和程序的单个进程。线程可以称为轻量级进程。线程需要更少的资源来创建和驻留在进程中,并且可以在进程内共享资源。2:多线程编程有什么好处?在多线程程序中,多个线程并发执行以提高程序的效率,CPU不会因为一个线程需要等待资源而进入空闲状态。多个线程共享堆内存,因此创建多个线程来执行某些任务比创建多个进程要好。例如,Servlet优于CGI,因为Servlet支持多线程,而CGI不支持。3:用户线程和守护线程有什么区别?当我们在Java程序中创建一个线程时,它被称为用户线程。守护线程是在后台执行的线程,不会阻止JVM终止。当没有用户线程在运行时,JVM关闭程序并退出。守护线程创建的子线程仍然是守护线程。4:我们如何创建线程?创建线程有两种方法:一种是实现Runnable接口,然后将其传递给Thread的构造函数,创建一个Thread对象;另一种是直接继承Thread类。5:线程生命周期有哪些不同?当我们在Java程序中创建一个新的线程时,它的状态是New。当我们调用线程的start()方法时,状态变为Runnable。线程调度器会为Runnable线程池中的线程分配CPU时间,并将它们的状态变为Running。其他线程状态是Waiting、Blocked和Dead。6:可以直接调用Thread类的run()方法吗?当然可以,但是如果我们调用了Thread的run()方法,它的行为就和普通方法一样了,为了在新的线程中执行我们的代码,就必须使用Thread.start()方法。7:如何暂停正在运行的线程一段时间?我们可以使用Thread类的Sleep()方法让线程暂停一段时间。注意,这并没有终止线程,一旦线程从睡眠中醒来,线程的状态就会变为Runnable,并根据线程调度,执行。8:你对线程优先级的理解是什么?每个线程都有优先级。一般来说,高优先级的线程在运行时会有优先权,但这取决于线程调度的实现。此实现依赖于操作系统。我们可以定义线程的优先级,但这并不能保证高优先级线程会先于低优先级线程执行。线程优先级是一个int变量(从1-10),1代表最高优先级,10代表最高优先级。9:什么是线程调度器和时间片?线程调度程序是一种操作系统服务,负责将CPU时间分配给处于Runnable状态的线程。一旦我们创建了一个线程并启动它,它的执行就取决于线程调度器的实现。时间分片是指将可用的CPU时间分配给可用的Runnable线程的过程。分配CPU时间可以基于线程优先级或线程等待时间。线程调度不受Java虚拟机控制,所以最好由应用程序来控制(即不要让你的程序依赖于线程的优先级)。10:在多线程中,什么是上下文切换?上下文切换是存储和恢复CPU状态的过程,它使线程执行能够从中断点恢复执行。上下文切换是多任务操作系统和多线程环境的基本特征。11:为什么Thread类的sleep()和yield()方法是静态的?Thread类的sleep()和yield()方法将在当前执行的线程上运行。所以在其他等待线程上调用这些方法是没有意义的。这就是为什么这些方法是静态的。它们可以工作在当前正在执行的线程中,避免程序员误以为它们可以从其他非运行线程中调用。12:如何保证线程安全?在Java中有很多方法可以确保线程安全——同步、使用原子并发类、实现并发锁、使用volatile关键字、使用不可变类和线程安全类。在线程安全教程中,您可以了解更多信息。13:如何创建守护线程?使用Thread类的setDaemon(true)方法将线程设置为守护线程。需要注意的是,这个方法需要在调用start()方法之前调用,否则会抛出IllegalThreadStateException。14:什么是ThreadLocal?ThreadLocal用于创建线程局部变量。我们知道一个对象的所有线程都会共享它的全局变量,所以这些变量不是线程安全的,我们可以使用同步技术。但是当我们不想使用同步时,我们可以选择ThreadLocal变量。每个线程都会有自己的Thread变量,它们可以使用get()set()方法来获取它们的默认值或者在线程内部改变它们的值。ThreadLocal实例通常希望它们是与线程状态关联的私有静态属性。二:Java并发面试问题一:Executors框架是什么?Executor框架是在Java5中通过java.util.concurrent.Executor接口引入的。Executor框架是一个异步任务的框架,异步任务根据一组执行策略被调用、调度、执行和控制。强制创建线程会导致应用程序内存溢出。所以创建线程池是一个比较好的解决方案,因为可以限制线程的数量,并且可以回收再利用这些线程。使用Executors框架可以轻松创建线程池。2:什么是Callable和Future?Java5在concurrency包中引入了java.util.concurrent.Callable接口,它与Runnable接口非常相似,但是它可以返回一个对象或者抛出异常。:Callable接口使用泛型来定义它的返回类型。Executors类提供了一些有用的方法来在线程池中执行Callable任务。由于Callable任务是并行的,我们必须等待它返回的结果。java.util.concurrent.Future对象为我们处理了这个。线程池提交Callable任务后,返回一个Future对象。使用它,我们可以知道Callable任务的状态,并得到Callable返回的执行结果。Future提供了get()方法,让我们可以等待Callable结束,获取它的执行结果。3:什么是FutureTask?FutureTask是Future的基本实现,我们可以将它与Executors一起使用来处理异步任务。通常我们不需要使用FutureTask类,但是当我们打算重写Future接口的一些方法并保持原有的基本实现时,它就变得非常有用。我们可以继承它并覆盖我们需要的方法。4:并发容器的实现是什么?Java集合类是快速失败的,这意味着当集合发生变化并且线程正在使用迭代器遍历集合时,迭代器的next()方法将抛出ConcurrentModificationException。并发容器支持并发遍历和并发更新。主要类有ConcurrentHashMap、CopyOnWriteArrayList和CopyOnWriteArraySet。5:什么是Executors类?Executors为Executor、ExecutorService、ScheduledExecutorService、ThreadFactory和Callable类提供了一些工具方法。执行器可用于轻松创建线程池。
