1.守护线程和用户线程区别


JVM会等待非守护线程完成后关闭, 但不会等待守护线程

2.线程的生命周期


  • 五个状态:新建,可运行(就绪),运行,阻塞,死亡
  • 三种阻塞原因:sleep,wait,suspend
  • 生命周期

多线程-LMLPHP

以及

多线程-LMLPHP

以及

多线程-LMLPHP

3.如何结束一个一直运行的线程


场景一: 中断处于运行状态的线程

通常,我们通过“标记”方式终止处于“运行状态”的线程

  1. 中断标记
@Override
public void run() {
    while (!isInterrupted()) {
        // 执行任务...
    }
}

说明:isInterrupted()是判断线程的中断标记是不是为true。当线程处于运行状态,并且我们需要终止它时;可以调用线程的interrupt()方法,使用线程的中断标记为true,即isInterrupted()会返回true。此时,就会退出while循环。注意:interrupt()并不会终止处于“运行状态”的线程!它会将线程的中断标记设为true。`

  1. 额外标记(自定义标记)
private volatile boolean flag= true;
@Override
public void run() {
    while (flag) {
        // 执行任务...
    }
}

注意:将flag定义为volatile类型,是为了保证flag的可见性。即其它线程通过stopTask()修改了flag之后,本线程能看到修改后的flag的值。

场景二: 中断处于阻塞状态的线程

使用interrupt()
当线程由于被调用了sleep(), wait(), join()等方法而进入阻塞状态;若此时调用线程的interrupt()将线程的中断标记设为true。由于处于阻塞状态,中断标记会被清除,同时产生一个InterruptedException异常。将InterruptedException放在适当的为止就能终止线程,形式如下:

@Override
public void run() {
    try {
        while (true) {
            // 执行任务...
        }
    } catch (InterruptedException ie) {
        // 由于产生InterruptedException异常,退出while(true)循环,线程终止!
    }
}

参考 https://www.cnblogs.com/skywang12345/p/3479949.html

4.一个线程运行时发生异常会怎样


如果这个异常没有被捕获的话,这个线程就停止执行了。
另外重要的一点是:如果这个线程持有某个某个对象的监视器,那么这个对象监视器会被立即释放

5.创建线程的方式及实现


  • 方式一,继承 Thread 类创建线程类。
  • 方式二,通过 Runnable 接口创建线程类。
    此方式可以使用线程池
  • 方式三,通过 Callable 和 Future 创建线程。
    此方式可以使用线程池

6.start 和 run 方法有什么区别


调用start()将创建新线程,run()将被执行;
直接调用run(),则不会创建线程,run()将作为普通方法执行

7.如何使用 wait + notify 实现通知机制


  • wait和notify都属于Object类的,故所有类都可以调用这两个方法。
  • 对象调用wait会阻塞当前线程,并释放对象锁
  • 调用notify则不会释放对象锁,但是会随机唤醒一个线程,等当前线程继续执行完notify()之后,synchronized之内的代码。唤醒的线程则需要抢到锁才能执行。
  • 其他通信机制:Condition,CountDownLatch,Queue,Future等

8.Thread类的 sleep 方法和对象的 wait 方法都可以让线程暂停执行,它们有什么区别


  • sleep()是Thread的静态方法,调用sleep会让当前线程让出CPU给其他线程,但是并不释放持有的锁。休眠时间结束后当前线程进入就绪状态等待CPU时间片。
  • wait()是Object的方法,调用对象的wait()会让当前线程释放对象的锁,当前线程将进入对象等待池,只有调用对象的notify()notifyAll(),才能唤醒等待线程,如果线程再次获取了锁就可以进入就绪状态。

为什么你应该在循环中检查等待条件


https://blog.csdn.net/qq_35181209/article/details/77362297

sleep、join、yield 方法有什么区别


  • sleep让出当前线程CPU并进入休眠,让其他线程有机会继续执行,但当前线程并不释放对象锁
  • yield和 sleep 方法类似,也不会释放“锁标志”。区别在于它没有参数,不能设置休眠时间,所以休眠线程可能又马上能进入执行状态。同时yield只会让出CPU给同优先级或高优先级线程。在实际场景下很少用yield.
  • 让一个线程 B “加入”到另外一个线程 A 的尾部

sleep(0) 有什么用途


线程暂时放弃 CPU

你如何确保 main 方法所在的线程是 Java 程序最后结束的线程


使用 Thread 类的 #join() 方法

interrupt ,interrupted 和 isInterrupted 方法的区别


  • interrupt:调用该方法的线程的状态为将被置为”中断”状态
  • interrupted: 查询当前线程的中断状态,会清除状态
  • isInterrupted:查询当前线程的中断状态,不会清除状态

Servlet 是线程安全吗


Servlet 是单实例多线程的,不安全

单例模式的线程安全性


单例模式的线程安全是指:某个单例类的实例在多线程环境下只会被创建一个。
  • 饿汉式单例模式的写法:线程安全
public class Singleton {
    private static final Singleton INSTANCE=new Singleton();
    private Singleton(){}
    public static Singleton getInstance(){
        return INSTANCE;
    }
}

优点:类加载即创建单例,整个过程不会有第二个对象,单例线程安全。
缺点:过早创建,影响性能。

  • 懒汉式单例模式的写法:非线程安全
  public class Singleton{
      private static Singleton instance = null;
      private Singleton(){}
      public static Singleton newInstance(){
          if(null == instance){
              instance = new Singleton();
          }
          return instance;
      }
  }

优点:需要时才创建
缺点:多线程环境会创建多个对象
改造:

  public class Singleton {
      private static Singleton instance;
      private Singleton(){
      }
      public static synchronized Singleton getInstance(){
          if(instance == null){
              instance = new Singleton();
          }
          return instance;
      }
  }

说明:可以保存单例多线程安全,但是synchronized方法效率低

  • 双检锁(DCL)单例模式的写法:线程安全
  public class Singleton {
      private static Singleton instance;
      //private Volatitle static Singleton instance;
      /*兼容JDK1.5的bug:对于instance = new Singleton(),JVM执行指令不确定,导致其他线程取到的instance可能还未初始化*/
      private Singleton(){}
      public static Singleton getInstance(){
          if(instance == null){
              synchronized (Singleton.class){
                  if(instance == null){
                      instance = new Singleton();
                  }
              }
          }
          return instance;
      }
  }

单例模式参考 https://www.jianshu.com/p/12d1a151982e

多线程同步和互斥有几种实现方法,都是什么

什么是 ThreadLocal 变量

在多线程环境下,SimpleDateFormat 是线程安全的吗

什么是Java Timer 类

你有哪些多线程开发良好的实践

synchronized 的原理是什么

Java 如何实现“自旋”(spin)

volatile 实现原理

什么场景下可以使用 volatile 替换 synchronized、

什么是死锁、活锁

Java AQS

什么是可重入锁(ReentrantLock)

synchronized 和 ReentrantLock 异同

ReadWriteLock 是什么

Condition 是什么

用三个线程按顺序循环打印 abc 三个字母,比如 abcabcabc

LockSupport 是什么

CopyOnWriteArrayList 可以用于什么应用场景

什么是阻塞队列?有什么适用场景

Java 提供了哪些阻塞队列的实现

什么是双端队列

延迟队列的实现方式,DelayQueue 和时间轮算法的异同

简述 ConcurrentLinkedQueue 和 LinkedBlockingQueue 的用处和不同之处?

CAS 操作有什么缺点

说说 CountDownLatch 原理

什么是 Executor 框架

讲讲线程池的实现原理

创建线程池的几种方式

线程池执行任务的过程

**如何让一段程序并发的执行,并最终汇总结果

04-06 07:35