Skip to content

JUC - 知识体系

JUC 是 java.util.concurrent 包的简称,在 Java5.0 添加,目的就是为了更好的支持高并发任务。让开发者进行多线程编程时减少竞争条件和死锁的问题。

别轻易使用成员变量,因为多线程会导致成员变量成为共享的资源,可能导致成员变量被多个线程进行修改,不安全。

所以能使用局部变量,就使用局部变量,大部分情况下,它是线程安全的。

什么时候局部变量不安全呢?发生了逃逸,即局部变量脱离所在的作用域,出现在其他方法里被使用,可能导致子类继承父类重写该方法,导致该局部变量被其他线程共享,如下:

java
public abstract class Father {

    public void bar() {
        // 是否安全
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        foo(sdf);
    }

    public void foo(SimpleDateFormat sdf);

    public static void main(String[] args) {
        new Test().bar();
    }
}

一个子类继承 Test,重写 foo 方法

java
public class Son extends Father{
  public void foo(SimpleDateFormat sdf) {
      String dateStr = "1999-10-11 00:00:00";
      for (int i = 0; i < 20; i++) {
          new Thread(() -> {
              try {
                  sdf.parse(dateStr);
              } catch (ParseException e) {
                  e.printStackTrace();
              }
          }).start();
      }
  }
}

sdf 对象在 main 线程的 bar 方法创建,却在子类的另一个线程执行 parse 方法,所以线程不安全。

线程不安全概念:一个对象在当前线程被使用时,另一个线程也在使用该对象,导致不安全。

解决 foo 线程不安全方法(局部变量在多个方法间传递问题)就是设置方法为 private,这样就不会被子类重写。