面试常见问题之线程部分 | Java Debug 笔记

本文正在参加「Java主题月 – Java Debug笔记活动」,详情查看<活动链接>

下面将面试中常见问题进行汇总,关于线程部分常遇见的问题如下:

1、使用过线程么?线程如何实现?

通过继承 Thread 类、实现Runnable 接口,在run方法中实现功能或业务逻辑。

2、线程中start和run方法有什么区别和联系?

调用start方法可启动线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行run()方法,即:线程要执行的内容。

而run方法只是线程里面一个普通方法的调用而已,还是在主线程里执行。如果直接调用run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到写线程的目的。

public static void main(String args[]) {
 
        Thread t = new Thread() {
 
            public void run() {
 
                pong();
 
            }
 
        };
 
        t.start();
 
        System.out.print("ping");
 
 }
 
 
public static void pong() {
 
        System.out.print("pong");
 
 }
复制代码

输出结果: pingpong

public static void main(String args[]) {
 
        Thread t = new Thread() {
 
            public void run() {
 
                pong();
 
            }
 
        };
 
        t.run();
 
        System.out.print("ping");
 
    }
 
 
 
public  static void pong() {
 
        System.out.print("pong");
 
 }
复制代码

输出结果:pongping

通过以上两个程序实例,可以很容易的区分出start()方法和run()方法的区别:

  • t.start(); 该行代码相当于是启动线程
  • t.run(); 该行代码相当于是使用t这个类中的run方法而已。

3、了解过线程死锁么?如何有效的避免线程死锁?

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外界作用下,它们都将无法进行下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

避免死锁最简单的方法就是阻止循环等待条件,将系统中所有的资源设置标志位、排序,规定所有的进程申请资源必须以一定的顺序(升序或降序)做操作来避免死锁。

4、项目中有没有用过线程池 ?怎么用的 ?

使用过。我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题:如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。

通过使用线程池就可以解决这个问题,使得线程可以复用,就是执行完一个任务,并不被销毁,而是可以继续执行其他的任务。Java的线程池最核心是ThreadPoolExecutor类,线程池底层都是通过 ThreadPoolExecutor 来实现的:

public ThreadPoolExecutor(int  corePoolSize,                           
                          int  maximumPoolSize,                          
                          long  keepAliveTime, 
                          TimeUnit  unit,                         
                          BlockingQueue<Runnable>  workQueue,                           
                          ThreadFactory  threadFactory,                           
                          RejectedExecutionHandler  handler)
复制代码

其中参数的意思分别为:

  • corePoolSize:线程池里最小线程数
  • maximumPoolSize:线程池里最大线程数量,超过最大线程时候会使用 RejectedExecutionHandler
  • keepAliveTime:线程最大的存活时间,超过这个时间就会被回收
  • unit:线程最大的存活时间的单位
  • workQueue:缓存需要执行的异步任务的队列
  • threadFactory:新建线程工厂
  • handler:拒绝策略,表示当 workQueue 已满,且池中的线程数达到maximumPoolSize时,线程池拒绝添加新任务时采取的策略。DiscardPolicy:抛弃当前任务,DiscardOldestPolicy:扔掉最旧的,CallerRunsPolicy:由向线程池提交任务的线程来执行该任务,AbortPolicy:抛出 RejectedExecutionException 异常。
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享