Java极客思维

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

 

开篇介绍

大家好,公众号【Java极客思维】近期会整理一些Java高频面试题分享给小伙伴,也希望看到的小伙伴在找工作过程中能够用得到!本章节主要针对Java一些多线程高频面试题进行分享。

 

Q1:

线程 和 进程有什么区别?

进程:

进程是程序运行资源分配的最小单位。进程内部有多个线程,会共享这个进程中的资源。

 

线程:

线程是CPU调度的最小单位。必须依赖进程而存在。

 

特点:

  • 线程的划分尺度小于进程,这使得多线程拥有高并发性;

  • 进程在运行时各自内存单元相互独立,线程之间内存共享;

  • 多线程开发可以拥有更好的性能和用户体验。

(注意:多线程开发对于其他程序是不友好的,占据大量CPU资源。)

 

Q2:

如何安全的终止线程?

理解中断:

线程自然终止:自然执行完 或 抛出未处理的异常。Java线程是协作式工作,而非抢占式工作;

  • stop()、resume()、suspend()三个方法已经在后续的jdk版本已过时,不建议使用;

    • stop()方法:会导致线程不正确释放资源;

    • suspend()方法:挂起,容易导致死锁;

  • 三种中断方式:

    • interrupt()方法:interrupt()方法中断一个线程,并不是强制关闭该线程,只是跟线程打声招呼,将线程的中断标志位置为true,线程是否中断,由线程本身决定;

    • inInterrupted()方法:判断当前线程是否处于中断状态;

    • static方法interrupted()方法:判断当前线程是否处于中断状态,并将中断标志位置为false;

(注意:方法里如果抛出InterruptedException,线程的中断标志位会被置为false,如果确实需要中断线程,则需要在catch里面再次调用interrupt()方法。)

 

Q3:

sleep() 和 wait() 有什么区别?

 

sleep()方法:

  • Thread类中的静态方法;

  • 当一个线程调用sleep()方法以后,不会释放同步资源锁,其他线程仍然会等待资源锁的释放。

 

wait()方法:

  • Object类提供的一个普通方法;

  • 而且必须同步资源锁对象在同步代码块或者同步方法中调用。当调用wait()方法后,当前线程会立刻释放掉同步锁资源。其他线程就有机会获得同步资源锁从而继续往下执行。

 

Q4:

notify() 和 notifyAll() 方法有什么区别?

尽量应该应用notifyAll()方法,如果用notify()方法的话,jvm会执行已经加入等待线程栈里面的第一个线程,给我们的一种感官就是随机的选择了一条线程,如果该线程达到条件就正好执行那一条,其实这是一个误区,这只是jvm会选择在线程栈里面的第一个线程来唤醒。因此用notify()方法的话,可能会造成信号丢失的情况。

 

Q5:

调用yield()、sleep()、wait()、notify()等方法对锁有何影响?

1. 线程在执行yield()以后,持有的锁是不会释放的;

2. sleep()方法被调用以后,持有的锁是不会释放的;

3. 调用方法之前,必须要先持有锁。调用了wait()方法以后,锁就会被释放,当wait方法返回的时候,线程会重新持有锁;

4. 调用方法之前,必须要先持有锁。调用notify()方法本身不会释放锁。

 

Q6:

创建多线程的方式有哪些?

 

方式一:继承Thread类

Thread本质上也是实现了Runnable接口的一个实例,它代表一个线程的实例,并且启动线程的唯一方法就是通过Thread类的start()实例方法。start()方法是一个native方法,它将启动一个新线程,并执行run()方法。这种方式实现多线程很简单,通过自己的类直接extend Thread,并重写run()方法,,就可以启动新线程并执行自定义的run()方法。例如:继承Thread类实现多线程,并在适合的地方启动线程。

public class MyThread extends Thread {
​  public void run() {
    System.out.println("MyThread.run()");
  }
}

MyThread myThread1 = new MyThread();
MyThread myThread2 = new MyThread();
myThread1.start();
myThread2.start();

 

方式二:实现Runnable接口的方式实现多线程,并且实例化Thread,传入自己的Thread实例,调用run()方法

public class MyThread implements Runnable {
  public void run() {
    System.out.println("MyThread.run()");
  }
}

MyThread myThread = new MyThread();
Thread thread = new Thread(myThread);
thread.start();

 

方式三:通过Callable 和 Future创建线程

class T implements Callable<String> {
  @Override
  public String call() throws Exception {
    return null;
  }
}

 

明天,会介绍多线程一些深入的知识,长按二维码关注我吧~

祝大家都能拿到心仪的offer!

 


点关注、不迷路

如果觉得文章不错,欢迎关注点赞收藏,你们的支持是我创作的动力,感谢大家。

如果文章写的有问题,请不要吝啬,欢迎留言指出,我会及时核查修改。

如果你还想更加深入的了解我,可以微信搜索「Java极客思维」进行关注。每天8:00准时推送技术文章,让你的上班路不在孤独,而且每月还有送书活动,助你提升硬实力!

posted on 2020-12-05 00:09  Java极客思维  阅读(126)  评论(0编辑  收藏  举报